fields.py 3.1 KB

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