fields.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from netaddr import IPNetwork
  2. from django.core.exceptions import ValidationError
  3. from django.db import models
  4. from .formfields import IPFormField
  5. from .lookups import (
  6. EndsWith, IEndsWith, IRegex, IStartsWith, NetContained, NetContainedOrEqual, NetContains, NetContainsOrEquals,
  7. NetHost, NetHostContained, NetMaskLength, Regex, StartsWith,
  8. )
  9. def prefix_validator(prefix):
  10. if prefix.ip != prefix.cidr.ip:
  11. raise ValidationError("{} is not a valid prefix. Did you mean {}?".format(prefix, prefix.cidr))
  12. class BaseIPField(models.Field):
  13. def python_type(self):
  14. return IPNetwork
  15. def from_db_value(self, value, expression, connection, context):
  16. return self.to_python(value)
  17. def to_python(self, value):
  18. if not value:
  19. return value
  20. try:
  21. return IPNetwork(value)
  22. except ValueError as e:
  23. raise ValidationError(e)
  24. def get_prep_value(self, value):
  25. if not value:
  26. return None
  27. return str(self.to_python(value))
  28. def form_class(self):
  29. return IPFormField
  30. def formfield(self, **kwargs):
  31. defaults = {'form_class': self.form_class()}
  32. defaults.update(kwargs)
  33. return super(BaseIPField, self).formfield(**defaults)
  34. class IPNetworkField(BaseIPField):
  35. """
  36. IP prefix (network and mask)
  37. """
  38. description = "PostgreSQL CIDR field"
  39. default_validators = [prefix_validator]
  40. def db_type(self, connection):
  41. return 'cidr'
  42. IPNetworkField.register_lookup(EndsWith)
  43. IPNetworkField.register_lookup(IEndsWith)
  44. IPNetworkField.register_lookup(StartsWith)
  45. IPNetworkField.register_lookup(IStartsWith)
  46. IPNetworkField.register_lookup(Regex)
  47. IPNetworkField.register_lookup(IRegex)
  48. IPNetworkField.register_lookup(NetContained)
  49. IPNetworkField.register_lookup(NetContainedOrEqual)
  50. IPNetworkField.register_lookup(NetContains)
  51. IPNetworkField.register_lookup(NetContainsOrEquals)
  52. IPNetworkField.register_lookup(NetMaskLength)
  53. class IPAddressField(BaseIPField):
  54. """
  55. IP address (host address and mask)
  56. """
  57. description = "PostgreSQL INET field"
  58. def db_type(self, connection):
  59. return 'inet'
  60. IPAddressField.register_lookup(EndsWith)
  61. IPAddressField.register_lookup(IEndsWith)
  62. IPAddressField.register_lookup(StartsWith)
  63. IPAddressField.register_lookup(IStartsWith)
  64. IPAddressField.register_lookup(Regex)
  65. IPAddressField.register_lookup(IRegex)
  66. IPAddressField.register_lookup(NetContained)
  67. IPAddressField.register_lookup(NetContainedOrEqual)
  68. IPAddressField.register_lookup(NetContains)
  69. IPAddressField.register_lookup(NetContainsOrEquals)
  70. IPAddressField.register_lookup(NetHost)
  71. IPAddressField.register_lookup(NetHostContained)
  72. IPAddressField.register_lookup(NetMaskLength)