fields.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 __init__(self, *args, **kwargs):
  71. kwargs['max_length'] = 17
  72. super(MACAddressField, self).__init__(*args, **kwargs)
  73. def db_type(self, connection):
  74. return 'macaddr'
  75. def to_python(self, value):
  76. if not value:
  77. return value
  78. try:
  79. return EUI(value, dialect=mac_unix_common)
  80. except AddrFormatError as e:
  81. raise ValidationError(e)
  82. def get_prep_value(self, value):
  83. if not value:
  84. return None
  85. return unicode(self.to_python(value))
  86. def formfield(self, **kwargs):
  87. defaults = {'form_class': MACAddressFormField}
  88. defaults.update(kwargs)
  89. return super(MACAddressField, self).formfield(**defaults)
  90. try:
  91. from south.modelsinspector import add_introspection_rules
  92. add_introspection_rules([], [
  93. "^netfields\.fields\.InetAddressField",
  94. "^netfields\.fields\.CidrAddressField",
  95. "^netfields\.fields\.MACAddressField",
  96. ])
  97. except ImportError:
  98. pass