fields.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from netaddr import IPAddress, IPNetwork, EUI
  2. from netaddr.core import AddrFormatError
  3. from django.db import models
  4. from django.core.exceptions import ValidationError
  5. from netfields.managers import NET_OPERATORS, NET_TEXT_OPERATORS
  6. from netfields.forms import InetAddressFormField, CidrAddressFormField, MACAddressFormField
  7. from netfields.mac import mac_unix_common
  8. class _NetAddressField(models.Field):
  9. empty_strings_allowed = False
  10. def __init__(self, *args, **kwargs):
  11. kwargs['max_length'] = self.max_length
  12. super(_NetAddressField, self).__init__(*args, **kwargs)
  13. def to_python(self, value):
  14. if not value:
  15. return value
  16. try:
  17. return self.python_type()(value)
  18. except AddrFormatError as e:
  19. raise ValidationError(e)
  20. def get_prep_lookup(self, lookup_type, value):
  21. if not value:
  22. return None
  23. if (lookup_type in NET_OPERATORS and
  24. NET_OPERATORS[lookup_type] not in NET_TEXT_OPERATORS):
  25. if lookup_type.startswith('net_contained') and value is not None:
  26. # Argument will be CIDR
  27. return unicode(value)
  28. return self.get_prep_value(value)
  29. return super(_NetAddressField, self).get_prep_lookup(
  30. lookup_type, value)
  31. def get_prep_value(self, value):
  32. if not value:
  33. return None
  34. return unicode(self.to_python(value))
  35. def get_db_prep_lookup(self, lookup_type, value, connection,
  36. prepared=False):
  37. if not value:
  38. return []
  39. if (lookup_type in NET_OPERATORS and
  40. NET_OPERATORS[lookup_type] not in NET_TEXT_OPERATORS):
  41. return [value] if prepared else [self.get_prep_value(value)]
  42. return super(_NetAddressField, self).get_db_prep_lookup(
  43. lookup_type, value, connection=connection, prepared=prepared)
  44. def formfield(self, **kwargs):
  45. defaults = {'form_class': self.form_class()}
  46. defaults.update(kwargs)
  47. return super(_NetAddressField, self).formfield(**defaults)
  48. class InetAddressField(_NetAddressField):
  49. description = "PostgreSQL INET field"
  50. max_length = 39
  51. __metaclass__ = models.SubfieldBase
  52. def db_type(self, connection):
  53. return 'inet'
  54. def python_type(self):
  55. return IPAddress
  56. def form_class(self):
  57. return InetAddressFormField
  58. class CidrAddressField(_NetAddressField):
  59. description = "PostgreSQL CIDR field"
  60. max_length = 43
  61. __metaclass__ = models.SubfieldBase
  62. def db_type(self, connection):
  63. return 'cidr'
  64. def python_type(self):
  65. return IPNetwork
  66. def form_class(self):
  67. return CidrAddressFormField
  68. class MACAddressField(models.Field):
  69. description = "PostgreSQL MACADDR field"
  70. def db_type(self, connection):
  71. return 'macaddr'
  72. def to_python(self, value):
  73. if not value:
  74. return value
  75. try:
  76. return EUI(value, dialect=mac_unix_common)
  77. except AddrFormatError as e:
  78. raise ValidationError(e)
  79. def get_prep_value(self, value):
  80. if not value:
  81. return None
  82. return unicode(self.to_python(value))
  83. def formfield(self, **kwargs):
  84. defaults = {'form_class': MACAddressFormField}
  85. defaults.update(kwargs)
  86. return super(MACAddressField, self).formfield(**defaults)
  87. try:
  88. from south.modelsinspector import add_introspection_rules
  89. add_introspection_rules([], [
  90. "^netfields\.fields\.InetAddressField",
  91. "^netfields\.fields\.CidrAddressField",
  92. "^netfields\.fields\.MACAddressField",
  93. ])
  94. except ImportError:
  95. pass