Skip to content
Snippets Groups Projects
Commit 6071f678 authored by Michael Fladischer's avatar Michael Fladischer
Browse files

Import python-django-netfields_0.7.2.orig.tar.gz

parent 741ac482
No related branches found
No related tags found
No related merge requests found
Showing
with 493 additions and 34 deletions
- 0.7.2
* Fix issue where prefetch_related returns empty querysets (Jay McEntire)
* Improve validation error messages to include the underlying error (Diego
Gaustein)
* Strip extraneous whitespace around form inputs
- 0.7.1
* Fix issue with recent psycopg2 releases (Jonas Genannt)
* Add a lookup for exact CIDR prefix length (Joey Wilhelm)
* Use proper unicode type when casting ipaddress/ipnetwork objects for
queries
* Support array aggregation with netfields (orf)
* compatibility with template based widgets (Leo Honkanen)
- 0.7
* Added support for Django 1.10
* Added __overlaps lookup (Emre Hasegeli)
......
PKG-INFO 0 → 100644
Metadata-Version: 1.1
Name: django-netfields
Version: 0.7.2
Summary: Django PostgreSQL netfields implementation
Home-page: https://github.com/jimfunk/django-postgresql-netfields
Author: James Oakley
Author-email: jfunk@funktronics.ca
License: BSD
Description: Django PostgreSQL Netfields
===========================
.. image:: https://secure.travis-ci.org/jimfunk/django-postgresql-netfields.png
This project is an attempt at making proper PostgreSQL net related fields for
Django. In Django pre 1.4 the built in ``IPAddressField`` does not support IPv6
and uses an inefficient ``HOST()`` cast in all lookups. As of 1.4 you can use
``GenericIPAddressField`` for IPv6, but the casting problem remains.
In addition to the basic ``IPAddressField`` replacement a ``CIDR`` and
a ``MACADDR`` field have been added. This library also provides a manager that
allows for advanced IP based lookup directly in the ORM.
In Python, the values of the IP address fields are represented as types from
the ipaddress_ module. In Python 2.x, a backport_ is used. The MAC address
field is represented as an EUI type from the netaddr_ module.
.. _ipaddress: https://docs.python.org/3/library/ipaddress.html
.. _backport: https://pypi.python.org/pypi/ipaddress/
.. _netaddr: http://pythonhosted.org/netaddr/
Dependencies
------------
Current version of code is targeting Django >= 1.8 support, as this relies
heavily on ORM internals and supporting multiple versions is especially tricky.
Getting started
---------------
Make sure ``netfields`` is in your ``PYTHONPATH`` and in ``INSTALLED_APPS``.
``InetAddressField`` will store values in PostgreSQL as type ``INET``. In
Python, the value will be represented as an ``ipaddress.ip_interface`` object
representing an IP address and netmask/prefix length pair unless the
``store_prefix_length`` argument is set to `False``, in which case the value
will be represented as an ``ipaddress.ip_address`` object.
from netfields import InetAddressField, NetManager
class Example(models.Model):
inet = InetAddressField()
# ...
objects = NetManager()
``CidrAddressField`` will store values in PostgreSQL as type ``CIDR``. In
Python, the value will be represented as an ``ipaddress.ip_network`` object.
from netfields import CidrAddressField, NetManager
class Example(models.Model):
inet = CidrAddressField()
# ...
objects = NetManager()
``MACAddressField`` will store values in PostgreSQL as type ``MACADDR``. In
Python, the value will be represented as a ``netaddr.EUI`` object. Note that
the default text representation of EUI objects is not the same as that of the
``netaddr`` module. It is represented in a format that is more commonly used
in network utilities and by network administrators (``00:11:22:aa:bb:cc``).
from netfields import MACAddressField, NetManager
class Example(models.Model):
inet = MACAddressField()
# ...
For ``InetAddressField`` and ``CidrAddressField``, ``NetManager`` is required
for the extra lookups to be available. Lookups for ``INET`` and ``CIDR``
database types will be handled differently than when running vanilla Django.
All lookups are case-insensitive and text based lookups are avoided whenever
possible. In addition to Django's default lookup types the following have been
added:
``__net_contained``
is contained within the given network
``__net_contained_or_equal``
is contained within or equal to the given network
``__net_contains``
contains the given address
``__net_contains_or_equals``
contains or is equal to the given address/network
``__net_overlaps``
contains or contained by the given address
``__family``
matches the given address family
These correspond with the operators and functions from
http://www.postgresql.org/docs/9.4/interactive/functions-net.html
``CidrAddressField`` includes two extra lookups:
``__max_prefixlen``
Maximum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6
``__min_prefixlen``
Minimum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6
Related Django bugs
-------------------
* 11442_ - Postgresql backend casts inet types to text, breaks IP operations and IPv6 lookups.
* 811_ - IPv6 address field support.
https://docs.djangoproject.com/en/dev/releases/1.4/#extended-ipv6-support is also relevant
.. _11442: http://code.djangoproject.com/ticket/11442
.. _811: http://code.djangoproject.com/ticket/811
Similar projects
----------------
https://bitbucket.org/onelson/django-ipyfield tries to solve some of the same
issues as this library. However, instead of supporting just postgres via the proper
fields types the ipyfield currently uses a ``VARCHAR(39)`` as a fake unsigned 64 bit
number in its implementation.
History
-------
Main repo was originaly kept https://github.com/adamcik/django-postgresql-netfields
Late April 2013 the project was moved to https://github.com/jimfunk/django-postgresql-netfields
to pass the torch on to someone who actually uses this code actively :-)
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Utilities
Metadata-Version: 1.1
Name: django-netfields
Version: 0.7.2
Summary: Django PostgreSQL netfields implementation
Home-page: https://github.com/jimfunk/django-postgresql-netfields
Author: James Oakley
Author-email: jfunk@funktronics.ca
License: BSD
Description: Django PostgreSQL Netfields
===========================
.. image:: https://secure.travis-ci.org/jimfunk/django-postgresql-netfields.png
This project is an attempt at making proper PostgreSQL net related fields for
Django. In Django pre 1.4 the built in ``IPAddressField`` does not support IPv6
and uses an inefficient ``HOST()`` cast in all lookups. As of 1.4 you can use
``GenericIPAddressField`` for IPv6, but the casting problem remains.
In addition to the basic ``IPAddressField`` replacement a ``CIDR`` and
a ``MACADDR`` field have been added. This library also provides a manager that
allows for advanced IP based lookup directly in the ORM.
In Python, the values of the IP address fields are represented as types from
the ipaddress_ module. In Python 2.x, a backport_ is used. The MAC address
field is represented as an EUI type from the netaddr_ module.
.. _ipaddress: https://docs.python.org/3/library/ipaddress.html
.. _backport: https://pypi.python.org/pypi/ipaddress/
.. _netaddr: http://pythonhosted.org/netaddr/
Dependencies
------------
Current version of code is targeting Django >= 1.8 support, as this relies
heavily on ORM internals and supporting multiple versions is especially tricky.
Getting started
---------------
Make sure ``netfields`` is in your ``PYTHONPATH`` and in ``INSTALLED_APPS``.
``InetAddressField`` will store values in PostgreSQL as type ``INET``. In
Python, the value will be represented as an ``ipaddress.ip_interface`` object
representing an IP address and netmask/prefix length pair unless the
``store_prefix_length`` argument is set to `False``, in which case the value
will be represented as an ``ipaddress.ip_address`` object.
from netfields import InetAddressField, NetManager
class Example(models.Model):
inet = InetAddressField()
# ...
objects = NetManager()
``CidrAddressField`` will store values in PostgreSQL as type ``CIDR``. In
Python, the value will be represented as an ``ipaddress.ip_network`` object.
from netfields import CidrAddressField, NetManager
class Example(models.Model):
inet = CidrAddressField()
# ...
objects = NetManager()
``MACAddressField`` will store values in PostgreSQL as type ``MACADDR``. In
Python, the value will be represented as a ``netaddr.EUI`` object. Note that
the default text representation of EUI objects is not the same as that of the
``netaddr`` module. It is represented in a format that is more commonly used
in network utilities and by network administrators (``00:11:22:aa:bb:cc``).
from netfields import MACAddressField, NetManager
class Example(models.Model):
inet = MACAddressField()
# ...
For ``InetAddressField`` and ``CidrAddressField``, ``NetManager`` is required
for the extra lookups to be available. Lookups for ``INET`` and ``CIDR``
database types will be handled differently than when running vanilla Django.
All lookups are case-insensitive and text based lookups are avoided whenever
possible. In addition to Django's default lookup types the following have been
added:
``__net_contained``
is contained within the given network
``__net_contained_or_equal``
is contained within or equal to the given network
``__net_contains``
contains the given address
``__net_contains_or_equals``
contains or is equal to the given address/network
``__net_overlaps``
contains or contained by the given address
``__family``
matches the given address family
These correspond with the operators and functions from
http://www.postgresql.org/docs/9.4/interactive/functions-net.html
``CidrAddressField`` includes two extra lookups:
``__max_prefixlen``
Maximum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6
``__min_prefixlen``
Minimum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6
Related Django bugs
-------------------
* 11442_ - Postgresql backend casts inet types to text, breaks IP operations and IPv6 lookups.
* 811_ - IPv6 address field support.
https://docs.djangoproject.com/en/dev/releases/1.4/#extended-ipv6-support is also relevant
.. _11442: http://code.djangoproject.com/ticket/11442
.. _811: http://code.djangoproject.com/ticket/811
Similar projects
----------------
https://bitbucket.org/onelson/django-ipyfield tries to solve some of the same
issues as this library. However, instead of supporting just postgres via the proper
fields types the ipyfield currently uses a ``VARCHAR(39)`` as a fake unsigned 64 bit
number in its implementation.
History
-------
Main repo was originaly kept https://github.com/adamcik/django-postgresql-netfields
Late April 2013 the project was moved to https://github.com/jimfunk/django-postgresql-netfields
to pass the torch on to someone who actually uses this code actively :-)
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Utilities
AUTHORS
CHANGELOG
LICENSE
MANIFEST.in
README.rst
manage.py
requirements.txt
setup.py
testsettings.py
django_netfields.egg-info/PKG-INFO
django_netfields.egg-info/SOURCES.txt
django_netfields.egg-info/dependency_links.txt
django_netfields.egg-info/not-zip-safe
django_netfields.egg-info/requires.txt
django_netfields.egg-info/top_level.txt
netfields/__init__.py
netfields/apps.py
netfields/fields.py
netfields/forms.py
netfields/lookups.py
netfields/mac.py
netfields/managers.py
netfields/models.py
netfields/psycopg2_types.py
netfields/rest_framework.py
test/__init__.py
test/models.py
test/tests/__init__.py
test/tests/test_form_fields.py
test/tests/test_rest_framework_fields.py
test/tests/test_sql_fields.py
\ No newline at end of file
netaddr
django>=1.8
ipaddress
netfields
test
......@@ -18,6 +18,7 @@ from netfields.lookups import (
NetContains,
NetContainsOrEquals,
NetOverlaps,
Prefixlen,
Regex,
StartsWith,
)
......@@ -51,6 +52,7 @@ class NetfieldsConfig(AppConfig):
CidrAddressField.register_lookup(Family)
CidrAddressField.register_lookup(MaxPrefixlen)
CidrAddressField.register_lookup(MinPrefixlen)
CidrAddressField.register_lookup(Prefixlen)
InetAddressField.register_lookup(EndsWith)
InetAddressField.register_lookup(IEndsWith)
......
......@@ -19,6 +19,9 @@ class _NetAddressField(models.Field):
super(_NetAddressField, self).__init__(*args, **kwargs)
def from_db_value(self, value, expression, connection, context):
if isinstance(value, list):
# Aggregation detected, return a list of values
return [self.to_python(v) for v in value if v is not None]
return self.to_python(value)
def to_python(self, value):
......@@ -53,8 +56,15 @@ class _NetAddressField(models.Field):
return str(self.to_python(value))
def get_db_prep_value(self, value, connection, prepared=False):
if not value:
return None
# Django <= 1.8, ArrayField does not pass model to the base_field so we have to check for existance
model = getattr(self, 'model', None)
if model is None or model._meta.get_field(self.name).get_internal_type() == 'ArrayField':
is_array_field = True
else:
is_array_field = False
if prepared is False and is_array_field is False:
return self.get_prep_value(value)
return Inet(self.get_prep_value(value))
......@@ -150,8 +160,15 @@ class MACAddressField(models.Field):
return text_type(self.to_python(value))
def get_db_prep_value(self, value, connection, prepared=False):
if not value:
return None
# Django <= 1.8, ArrayField does not pass model to the base_field so we have to check for existance
model = getattr(self, 'model', None)
if model is None or model._meta.get_field(self.name).get_internal_type() == 'ArrayField':
is_array_field = True
else:
is_array_field = False
if prepared is False and is_array_field is False:
return self.get_prep_value(value)
return Macaddr(self.get_prep_value(value))
......
......@@ -5,6 +5,7 @@ from django import forms
import django
from django.forms.utils import flatatt
from django.utils.safestring import mark_safe
from django.utils.six import text_type
from django.core.exceptions import ValidationError
from netfields.mac import mac_unix_common
......@@ -17,7 +18,14 @@ class NetInput(forms.Widget):
# Default forms.Widget compares value != '' which breaks IP...
if value is None:
value = ''
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
if attrs is None:
attrs = {}
base_attrs = {
"type": self.input_type,
"name": name
}
base_attrs.update(attrs)
final_attrs = self.build_attrs(base_attrs)
if value:
final_attrs['value'] = value
return mark_safe(u'<input%s />' % flatatt(final_attrs))
......@@ -39,6 +47,9 @@ class InetAddressFormField(forms.Field):
if isinstance(value, _IPAddressBase):
return value
if isinstance(value, text_type):
value = value.strip()
try:
return ip_interface(value)
except ValueError as e:
......@@ -61,6 +72,9 @@ class CidrAddressFormField(forms.Field):
if isinstance(value, _BaseNetwork):
network = value
if isinstance(value, text_type):
value = value.strip()
try:
network = ip_network(value)
except ValueError as e:
......@@ -84,6 +98,9 @@ class MACAddressFormField(forms.Field):
if isinstance(value, EUI):
return value
if isinstance(value, text_type):
value = value.strip()
try:
return EUI(value, dialect=mac_unix_common)
except (AddrFormatError, TypeError):
......
......@@ -135,6 +135,15 @@ class Family(Transform):
class _PrefixlenMixin(object):
format_string = None
def as_sql(self, qn, connection):
assert self.format_string is not None, "Prefixlen lookups must specify a format_string"
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
params = lhs_params + rhs_params
return self.format_string % (lhs, rhs), params
def process_lhs(self, qn, connection, lhs=None):
lhs = lhs or self.lhs
lhs_string, lhs_params = qn.compile(lhs)
......@@ -147,19 +156,14 @@ class _PrefixlenMixin(object):
class MaxPrefixlen(_PrefixlenMixin, Lookup):
lookup_name = 'max_prefixlen'
def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
params = lhs_params + rhs_params
return '%s <= %s' % (lhs, rhs), params
format_string = '%s <= %s'
class MinPrefixlen(_PrefixlenMixin, Lookup):
lookup_name = 'min_prefixlen'
format_string = '%s >= %s'
def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
params = lhs_params + rhs_params
return '%s >= %s' % (lhs, rhs), params
class Prefixlen(_PrefixlenMixin, Lookup):
lookup_name = 'prefixlen'
format_string = '%s = %s'
......@@ -7,6 +7,12 @@ from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper
from django.db.models import sql, query
from django.db.models.fields import DateTimeField
try:
str_type = unicode
except NameError:
str_type = str
NET_OPERATORS = DatabaseWrapper.operators.copy()
for operator in ['contains', 'startswith', 'endswith']:
......@@ -79,5 +85,5 @@ class NetManager(models.Manager):
if isinstance(val, _BaseNetwork):
# Django will attempt to consume the _BaseNetwork iterator, which
# will convert it to a list of every address in the network
kwargs[key] = str(val)
kwargs[key] = str_type(val)
return super(NetManager, self).filter(*args, **kwargs)
......@@ -10,7 +10,7 @@ class Macaddr(Inet):
obj = psycopg2.extensions.adapt(self.addr)
if hasattr(obj, 'prepare'):
obj.prepare(self._conn)
return obj.getquoted() + psycopg2.extensions.b("::macaddr")
return obj.getquoted() + b"::macaddr"
# Register array types for CIDR and MACADDR (Django already registers INET)
......
......@@ -16,8 +16,8 @@ class NetfieldsField(serializers.CharField):
"""
try:
self.netfields_type(value).to_python(value)
except DjangoValidationError:
raise serializers.ValidationError("Invalid {} address.".format(self.address_type))
except DjangoValidationError as e:
raise serializers.ValidationError("Invalid {} address: {}".format(self.address_type, e.message))
class InetAddressField(NetfieldsField):
......
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
......@@ -22,7 +22,7 @@ if sys.version_info.major == 2:
setup(
name='django-netfields',
version='0.7',
version='0.7.2',
license='BSD',
description='Django PostgreSQL netfields implementation',
long_description=get_long_description(),
......
from django.contrib.postgres.fields import ArrayField
from django.db.models import Model
from django.db.models import Model, ForeignKey
from netfields import InetAddressField, CidrAddressField, MACAddressField, \
NetManager
......@@ -88,3 +88,13 @@ class MACArrayTestModel(Model):
class Meta:
db_table = 'macarray'
class AggregateTestModel(Model):
pass
class AggregateTestChildModel(Model):
parent = ForeignKey('AggregateTestModel', related_name='children')
network = CidrAddressField()
inet = InetAddressField()
......@@ -34,6 +34,11 @@ class TestInetAddressFormField(TestCase):
form = self.form_class({'field': '10.0.0.1.2'})
self.assertFalse(form.is_valid())
def test_form_ipv4_strip(self):
form = self.form_class({'field': ' 10.0.0.1 '})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], ip_interface('10.0.0.1'))
def test_form_ipv4_change(self):
instance = InetTestModel.objects.create(field='10.1.2.3/24')
form = self.form_class({'field': '10.1.2.4/24'}, instance=instance)
......@@ -42,7 +47,7 @@ class TestInetAddressFormField(TestCase):
instance = InetTestModel.objects.get(pk=instance.pk)
self.assertEqual(instance.field, ip_interface('10.1.2.4/24'))
def test_form_ipv6(self):
def test_form_ipv6_valid(self):
form = self.form_class({'field': '2001:0:1::2'})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], ip_interface('2001:0:1::2'))
......@@ -51,6 +56,11 @@ class TestInetAddressFormField(TestCase):
form = self.form_class({'field': '2001:0::1::2'})
self.assertFalse(form.is_valid())
def test_form_ipv6_strip(self):
form = self.form_class({'field': ' 2001:0:1::2 '})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], ip_interface('2001:0:1::2'))
def test_form_ipv6_change(self):
instance = InetTestModel.objects.create(field='2001:0:1::2/64')
form = self.form_class({'field': '2001:0:1::3/64'}, instance=instance)
......@@ -79,6 +89,12 @@ class TestNoPrefixInetAddressFormField(TestCase):
form = self.form_class({'field': '10.0.0.1.2'})
self.assertFalse(form.is_valid())
def test_form_ipv4_strip(self):
form = self.form_class({'field': ' 10.0.0.1 '})
self.assertTrue(form.is_valid())
# Form always passes ip_interface. Model field will return the requested type
self.assertEqual(form.cleaned_data['field'], ip_interface('10.0.0.1'))
def test_form_ipv4_change(self):
instance = NoPrefixInetTestModel.objects.create(field='10.1.2.3/24')
form = self.form_class({'field': '10.1.2.4/24'}, instance=instance)
......@@ -87,7 +103,7 @@ class TestNoPrefixInetAddressFormField(TestCase):
instance = NoPrefixInetTestModel.objects.get(pk=instance.pk)
self.assertEqual(instance.field, ip_address('10.1.2.4'))
def test_form_ipv6(self):
def test_form_ipv6_valid(self):
form = self.form_class({'field': '2001:0:1::2'})
self.assertTrue(form.is_valid())
# Form always passes ip_interface. Model field will return the requested type
......@@ -97,6 +113,12 @@ class TestNoPrefixInetAddressFormField(TestCase):
form = self.form_class({'field': '2001:0::1::2'})
self.assertFalse(form.is_valid())
def test_form_ipv6_strip(self):
form = self.form_class({'field': ' 2001:0:1::2 '})
self.assertTrue(form.is_valid())
# Form always passes ip_interface. Model field will return the requested type
self.assertEqual(form.cleaned_data['field'], ip_interface('2001:0:1::2'))
def test_form_ipv6_change(self):
instance = NoPrefixInetTestModel.objects.create(field='2001:0:1::2/64')
form = self.form_class({'field': '2001:0:1::3/64'}, instance=instance)
......@@ -134,11 +156,16 @@ class TestCidrAddressFormField(TestCase):
form = self.form_class({'field': '10.0.0.1.2/32'})
self.assertFalse(form.is_valid())
def test_form_ipv4_strip(self):
form = self.form_class({'field': ' 10.0.1.0/24 '})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], ip_network('10.0.1.0/24'))
def test_form_ipv4_bits_to_right_of_mask(self):
form = self.form_class({'field': '10.0.0.1.2/24'})
self.assertFalse(form.is_valid())
def test_form_ipv6(self):
def test_form_ipv6_valid(self):
form = self.form_class({'field': '2001:0:1::/64'})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], ip_network('2001:0:1::/64'))
......@@ -147,6 +174,11 @@ class TestCidrAddressFormField(TestCase):
form = self.form_class({'field': '2001:0::1::2/128'})
self.assertFalse(form.is_valid())
def test_form_ipv6_strip(self):
form = self.form_class({'field': ' 2001:0:1::/64 '})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], ip_network('2001:0:1::/64'))
def test_form_ipv6_bits_to_right_of_mask(self):
form = self.form_class({'field': '2001:0::1::2/64'})
self.assertFalse(form.is_valid())
......@@ -207,6 +239,11 @@ class TestMacAddressFormField(TestCase):
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], self.mac)
def test_strip(self):
form = MacAddressTestModelForm({'field': ' 00:aa:2b:c3:dd:44 '})
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data['field'], self.mac)
def test_invalid(self):
form = MacAddressTestModelForm({'field': 'notvalid'})
self.assertFalse(form.is_valid())
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from rest_framework import serializers
......@@ -12,30 +12,36 @@ class FieldsTestCase(unittest.TestCase):
class TestSerializer(serializers.Serializer):
ip = fields.InetAddressField()
serializer = TestSerializer(data={'ip': '10.0.0.'})
address = '10.0.0.'
serializer = TestSerializer(data={'ip': address})
with self.assertRaises(serializers.ValidationError) as e:
serializer.is_valid(raise_exception=True)
self.assertEqual(e.exception.detail['ip'], ['Invalid IP address.'])
self.assertEqual(e.exception.detail['ip'],
["Invalid IP address: %r does not appear to be an IPv4 or IPv6 interface" % address])
def test_validation_cidr_field(self):
class TestSerializer(serializers.Serializer):
cidr = fields.CidrAddressField()
serializer = TestSerializer(data={'cidr': '10.0.0.'})
address = '10.0.0.'
serializer = TestSerializer(data={'cidr': address})
with self.assertRaises(serializers.ValidationError) as e:
serializer.is_valid(raise_exception=True)
self.assertEqual(e.exception.detail['cidr'], ['Invalid CIDR address.'])
self.assertEqual(e.exception.detail['cidr'],
["Invalid CIDR address: %r does not appear to be an IPv4 or IPv6 network" % address])
def test_validation_mac_field(self):
class TestSerializer(serializers.Serializer):
mac = fields.MACAddressField()
serializer = TestSerializer(data={'mac': 'de:'})
address = 'de:'
serializer = TestSerializer(data={'mac': address})
with self.assertRaises(serializers.ValidationError) as e:
serializer.is_valid(raise_exception=True)
self.assertEqual(e.exception.detail['mac'], ['Invalid MAC address.'])
self.assertEqual(e.exception.detail['mac'], ["Invalid MAC address: failed to detect EUI version: %r" % address])
def test_validation_additional_validators(self):
def validate(value):
......@@ -44,7 +50,10 @@ class FieldsTestCase(unittest.TestCase):
class TestSerializer(serializers.Serializer):
ip = fields.InetAddressField(validators=[validate])
serializer = TestSerializer(data={'ip': 'de:'})
address = 'de:'
serializer = TestSerializer(data={'ip': address})
with self.assertRaises(serializers.ValidationError) as e:
serializer.is_valid(raise_exception=True)
self.assertItemsEqual(e.exception.detail['ip'], ['Invalid IP address.', 'Invalid.'])
self.assertItemsEqual(e.exception.detail['ip'],
["Invalid IP address: %r does not appear to be an IPv4 or IPv6 interface" % address,
'Invalid.'])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment