Ticket #811: genericipaddressfield.diff
File genericipaddressfield.diff, 29.4 KB (added by , 13 years ago) |
---|
-
docs/topics/forms/modelforms.txt
83 83 84 84 ``IPAddressField`` ``IPAddressField`` 85 85 86 ``GenericIPAddressField`` ``GenericIPAddressField`` 87 86 88 ``ManyToManyField`` ``ModelMultipleChoiceField`` (see 87 89 below) 88 90 -
docs/ref/models/fields.txt
760 760 An IP address, in string format (e.g. "192.0.2.30"). The admin represents this 761 761 as an ``<input type="text">`` (a single-line input). 762 762 763 ``GenericIPAddressField`` 764 ------------------------- 765 766 .. class:: GenericIPAddressField([protocols=both, unpack_ipv4_mapped=False, **options]) 767 768 .. versionadded:: 1.4 769 770 An IPv4 or IPv6 address, in string format (e.g. "192.0.2.30" or "2a02:42fe::4") 771 The admin represents this as an ``<input type="text">`` (a single-line input). 772 773 The IPv6 address normalization follows `RFC4291 section 2.2`_, including using 774 the IPv4 format suggested in paragraph 3 of that section, like ``::ffff:192.0.2.0``. 775 For example, ``2001:0::0:01`` would be normalized to ``2001::1``, and ``::ffff:0a0a:0a0a`` 776 to ``::ffff:10.10.10.10``. All characters are converted to lowercase. 777 778 .. _RFC4291 section 2.2: http://tools.ietf.org/html/rfc4291#section-2.2 779 780 .. attribute:: GenericIPAddressField.protocol 781 782 Limits valid inputs to the specified protocol. 783 Accepted values are ``both`` (default), ``IPv4`` 784 or ``IPv6``. Matching is case insensitive. 785 786 .. attribute:: GenericIPAddressField.unpack_ipv4_mapped 787 788 Unpack IPv4 mapped addresses, like ``::ffff::192.0.2.1``. 789 If this option is enabled, that address would be unpacked to 790 ``192.0.2.1``. Default is disabled. Can only be used 791 when ``protocol`` is set to ``both``. 792 763 793 ``NullBooleanField`` 764 794 -------------------- 765 795 -
docs/ref/validators.txt
130 130 A :class:`RegexValidator` instance that ensures a value looks like an IPv4 131 131 address. 132 132 133 ``validate_ipv6_address`` 134 ------------------------- 135 .. versionadded:: 1.4 136 137 .. data:: validate_ipv6_address 138 139 Uses :mod:`django.utils.ipv6` to check the validity of an IPv6 address. 140 141 ``validate_ipv46_address`` 142 -------------------------- 143 .. versionadded:: 1.4 144 145 .. data:: validate_ipv46_address 146 147 Uses both ``validate_ipv4_address`` and ``validate_ipv6_address`` to ensure 148 a value is either a valid IPv4 or IPv6 address. 149 133 150 ``validate_comma_separated_integer_list`` 134 151 ----------------------------------------- 135 152 .. data:: validate_comma_separated_integer_list -
docs/ref/forms/fields.txt
622 622 expression. 623 623 * Error message keys: ``required``, ``invalid`` 624 624 625 ``GenericIPAddressField`` 626 ~~~~~~~~~~~~~~~~~~~~~~~~~ 627 628 .. class:: GenericIPAddressField(**kwargs) 629 630 .. versionadded:: 1.4 631 632 A field containing either an IPv4 or an IPv6 address. 633 634 * Default widget: ``TextInput`` 635 * Empty value: ``''`` (an empty string) 636 * Normalizes to: A Unicode object. IPv6 addresses are 637 normalized as described below. 638 * Validates that the given value is a valid IP address, using regular 639 expressions. 640 * Error message keys: ``required``, ``invalid`` 641 642 The IPv6 address normalization follows `RFC4291 section 2.2`_, including using 643 the IPv4 format suggested in paragraph 3 of that section, like ``::ffff:192.0.2.0``. 644 For example, ``2001:0::0:01`` would be normalized to ``2001::1``, and ``::ffff:0a0a:0a0a`` 645 to ``::ffff:10.10.10.10``. All characters are converted to lowercase. 646 647 .. _RFC4291 section 2.2: http://tools.ietf.org/html/rfc4291#section-2.2 648 649 Takes two optional arguments: 650 651 .. attribute:: GenericIPAddressField.protocol 652 653 Limits valid inputs to the specified protocol. 654 Accepted values are ``both`` (default), ``IPv4`` 655 or ``IPv6``. Matching is case insensitive. 656 657 .. attribute:: GenericIPAddressField.unpack_ipv4_mapped 658 659 Unpack IPv4 mapped addresses, like ``::ffff::192.0.2.1``. 660 If this option is enabled, that address would be unpacked to 661 ``192.0.2.1``. Default is disabled. Can only be used 662 when ``protocol`` is set to ``both``. 663 625 664 ``MultipleChoiceField`` 626 665 ~~~~~~~~~~~~~~~~~~~~~~~ 627 666 -
django/db/models/fields/__init__.py
17 17 from django.utils.translation import ugettext_lazy as _ 18 18 from django.utils.encoding import smart_unicode, force_unicode, smart_str 19 19 from django.utils import datetime_safe 20 from django.utils.ipv6 import (clean_ipv6_address, is_valid_ipv6_address, 21 validate_configure_ipaddressfield_settings) 20 22 21 23 class NOT_PROVIDED: 22 24 pass … … 920 922 921 923 class IPAddressField(Field): 922 924 empty_strings_allowed = False 923 description = _("IP address")925 description = _("IPv4 address") 924 926 def __init__(self, *args, **kwargs): 925 927 kwargs['max_length'] = 15 926 928 Field.__init__(self, *args, **kwargs) … … 933 935 defaults.update(kwargs) 934 936 return super(IPAddressField, self).formfield(**defaults) 935 937 938 class GenericIPAddressField(Field): 939 empty_strings_allowed = True 940 description = _("IP address") 941 default_error_messages = {} 942 943 def __init__(self, protocol='both', unpack_ipv4_mapped=False, *args, **kwargs): 944 self.unpack_ipv4_mapped = unpack_ipv4_mapped 945 946 self.default_validators = validate_configure_ipaddressfield_settings( 947 protocol, unpack_ipv4_mapped, self.default_error_messages) 948 949 kwargs['max_length'] = 39 950 Field.__init__(self, *args, **kwargs) 951 952 def get_internal_type(self): 953 return "GenericIPAddressField" 954 955 def to_python(self, value): 956 if value and ':' in value: 957 return clean_ipv6_address(value, self.unpack_ipv4_mapped, self.default_error_messages['invalid']) 958 959 return value 960 961 def get_prep_value(self, value): 962 if value and ':' in value: 963 try: 964 return clean_ipv6_address(value, self.unpack_ipv4_mapped) 965 except ValidationError: 966 pass 967 968 return value 969 970 def formfield(self, **kwargs): 971 defaults = {'form_class': forms.GenericIPAddressField} 972 defaults.update(kwargs) 973 return super(GenericIPAddressField, self).formfield(**defaults) 974 975 936 976 class NullBooleanField(Field): 937 977 empty_strings_allowed = False 938 978 default_error_messages = { -
django/db/backends/sqlite3/creation.py
20 20 'IntegerField': 'integer', 21 21 'BigIntegerField': 'bigint', 22 22 'IPAddressField': 'char(15)', 23 'GenericIPAddressField': 'char(39)', 23 24 'NullBooleanField': 'bool', 24 25 'OneToOneField': 'integer', 25 26 'PositiveIntegerField': 'integer unsigned', -
django/db/backends/mysql/creation.py
19 19 'IntegerField': 'integer', 20 20 'BigIntegerField': 'bigint', 21 21 'IPAddressField': 'char(15)', 22 'GenericIPAddressField': 'char(39)', 22 23 'NullBooleanField': 'bool', 23 24 'OneToOneField': 'integer', 24 25 'PositiveIntegerField': 'integer UNSIGNED', -
django/db/backends/oracle/creation.py
27 27 'IntegerField': 'NUMBER(11)', 28 28 'BigIntegerField': 'NUMBER(19)', 29 29 'IPAddressField': 'VARCHAR2(15)', 30 'GenericIPAddressField': 'VARCHAR2(39)', 30 31 'NullBooleanField': 'NUMBER(1) CHECK ((%(qn_column)s IN (0,1)) OR (%(qn_column)s IS NULL))', 31 32 'OneToOneField': 'NUMBER(11)', 32 33 'PositiveIntegerField': 'NUMBER(11) CHECK (%(qn_column)s >= 0)', -
django/db/backends/postgresql_psycopg2/introspection.py
12 12 700: 'FloatField', 13 13 701: 'FloatField', 14 14 869: 'IPAddressField', 15 869: 'GenericIPAddressField', 15 16 1043: 'CharField', 16 17 1082: 'DateField', 17 18 1083: 'TimeField', -
django/db/backends/postgresql_psycopg2/creation.py
21 21 'IntegerField': 'integer', 22 22 'BigIntegerField': 'bigint', 23 23 'IPAddressField': 'inet', 24 'GenericIPAddressField': 'inet', 24 25 'NullBooleanField': 'boolean', 25 26 'OneToOneField': 'integer', 26 27 'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)', -
django/forms/fields.py
9 9 import time 10 10 import urlparse 11 11 import warnings 12 import socket 12 13 from decimal import Decimal, DecimalException 13 14 try: 14 15 from cStringIO import StringIO … … 21 22 from django.utils.translation import ugettext_lazy as _ 22 23 from django.utils.encoding import smart_unicode, smart_str, force_unicode 23 24 from django.utils.functional import lazy 25 from django.utils.ipv6 import clean_ipv6_address, validate_configure_ipaddressfield_settings 24 26 25 27 # Provide this import for backwards compatibility. 26 28 from django.core.validators import EMPTY_VALUES … … 37 39 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 38 40 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', 39 41 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 40 'SplitDateTimeField', 'IPAddressField', ' FilePathField', 'SlugField',41 ' TypedChoiceField', 'TypedMultipleChoiceField'42 'SplitDateTimeField', 'IPAddressField', 'GenericIPAddressField', 'FilePathField', 43 'SlugField', 'TypedChoiceField', 'TypedMultipleChoiceField' 42 44 ) 43 45 44 46 … … 955 957 default_validators = [validators.validate_ipv4_address] 956 958 957 959 960 class GenericIPAddressField(CharField): 961 default_error_messages = {} 962 963 def __init__(self, protocol='both', unpack_ipv4_mapped=False, *args, **kwargs): 964 self.unpack_ipv4_mapped = unpack_ipv4_mapped 965 966 self.default_validators = validate_configure_ipaddressfield_settings( 967 protocol, unpack_ipv4_mapped, self.default_error_messages) 968 969 super(GenericIPAddressField, self).__init__(*args, **kwargs) 970 971 def to_python(self, value): 972 if not value: 973 return '' 974 975 if value and ':' in value: 976 return clean_ipv6_address(value, self.unpack_ipv4_mapped, self.default_error_messages['invalid']) 977 978 return value 979 980 958 981 class SlugField(CharField): 959 982 default_error_messages = { 960 983 'invalid': _(u"Enter a valid 'slug' consisting of letters, numbers," -
django/core/validators.py
5 5 from django.core.exceptions import ValidationError 6 6 from django.utils.translation import ugettext_lazy as _ 7 7 from django.utils.encoding import smart_unicode 8 from django.utils.ipv6 import is_valid_ipv6_address 8 9 9 10 # These values, if given to validate(), will trigger the self.required check. 10 11 EMPTY_VALUES = (None, '', [], (), {}) … … 145 146 ipv4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$') 146 147 validate_ipv4_address = RegexValidator(ipv4_re, _(u'Enter a valid IPv4 address.'), 'invalid') 147 148 149 def validate_ipv6_address(value): 150 if not is_valid_ipv6_address(value): 151 raise ValidationError(_(u'Enter a valid IPv6 address.'), code='invalid') 152 153 def validate_ipv46_address(value): 154 try: 155 validate_ipv4_address(value) 156 except ValidationError: 157 try: 158 validate_ipv6_address(value) 159 except ValidationError: 160 raise ValidationError(_(u'Enter a valid IPv4 or IPv6 address.'), code='invalid') 161 148 162 comma_separated_int_list_re = re.compile('^[\d,]+$') 149 163 validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _(u'Enter only digits separated by commas.'), 'invalid') 150 164 -
tests/modeltests/validators/tests.py
52 52 (validate_ipv4_address, '25,1,1,1', ValidationError), 53 53 (validate_ipv4_address, '25.1 .1.1', ValidationError), 54 54 55 # validate_ipv6_address uses django.utils.ipv6, which 56 # is tested in much greater detail in it's own testcase 57 (validate_ipv6_address, 'fe80::1', None), 58 (validate_ipv6_address, '::1', None), 59 (validate_ipv6_address, '1:2:3:4:5:6:7:8', None), 60 61 (validate_ipv6_address, '1:2', ValidationError), 62 (validate_ipv6_address, '::zzz', ValidationError), 63 (validate_ipv6_address, '12345::', ValidationError), 64 65 (validate_ipv46_address, '1.1.1.1', None), 66 (validate_ipv46_address, '255.0.0.0', None), 67 (validate_ipv46_address, '0.0.0.0', None), 68 (validate_ipv46_address, 'fe80::1', None), 69 (validate_ipv46_address, '::1', None), 70 (validate_ipv46_address, '1:2:3:4:5:6:7:8', None), 71 72 (validate_ipv46_address, '256.1.1.1', ValidationError), 73 (validate_ipv46_address, '25.1.1.', ValidationError), 74 (validate_ipv46_address, '25,1,1,1', ValidationError), 75 (validate_ipv46_address, '25.1 .1.1', ValidationError), 76 (validate_ipv46_address, '1:2', ValidationError), 77 (validate_ipv46_address, '::zzz', ValidationError), 78 (validate_ipv46_address, '12345::', ValidationError), 79 55 80 (validate_comma_separated_integer_list, '1', None), 56 81 (validate_comma_separated_integer_list, '1,2,3', None), 57 82 (validate_comma_separated_integer_list, '1,2,3,', None), -
tests/modeltests/validation/tests.py
2 2 from django.test import TestCase 3 3 from django.core.exceptions import NON_FIELD_ERRORS 4 4 from modeltests.validation import ValidationTestCase 5 from modeltests.validation.models import Author, Article, ModelToValidate 5 from modeltests.validation.models import (Author, Article, ModelToValidate, 6 GenericIPAddressTestModel, GenericIPAddressWithUnpackUniqueTestModel) 6 7 7 8 # Import other tests for this package. 8 9 from modeltests.validation.validators import TestModelsWithValidators … … 77 78 mtv = ModelToValidate(number=10, name='Some Name'*100) 78 79 self.assertFailsValidation(mtv.full_clean, ['name',]) 79 80 81 80 82 class ArticleForm(forms.ModelForm): 81 83 class Meta: 82 84 model = Article … … 124 126 article = Article(author_id=self.author.id) 125 127 form = ArticleForm(data, instance=article) 126 128 self.assertEqual(form.errors.keys(), ['pub_date']) 129 130 131 class GenericIPAddressFieldTests(ValidationTestCase): 132 133 def test_correct_generic_ip_passes(self): 134 giptm = GenericIPAddressTestModel(generic_ip="1.2.3.4") 135 self.assertEqual(None, giptm.full_clean()) 136 giptm = GenericIPAddressTestModel(generic_ip="2001::2") 137 self.assertEqual(None, giptm.full_clean()) 138 139 def test_invalid_generic_ip_raises_error(self): 140 giptm = GenericIPAddressTestModel(generic_ip="294.4.2.1") 141 self.assertFailsValidation(giptm.full_clean, ['generic_ip',]) 142 giptm = GenericIPAddressTestModel(generic_ip="1:2") 143 self.assertFailsValidation(giptm.full_clean, ['generic_ip',]) 144 145 def test_correct_v4_ip_passes(self): 146 giptm = GenericIPAddressTestModel(v4_ip="1.2.3.4") 147 self.assertEqual(None, giptm.full_clean()) 148 149 def test_invalid_v4_ip_raises_error(self): 150 giptm = GenericIPAddressTestModel(v4_ip="294.4.2.1") 151 self.assertFailsValidation(giptm.full_clean, ['v4_ip',]) 152 giptm = GenericIPAddressTestModel(v4_ip="2001::2") 153 self.assertFailsValidation(giptm.full_clean, ['v4_ip',]) 154 155 def test_correct_v6_ip_passes(self): 156 giptm = GenericIPAddressTestModel(v6_ip="2001::2") 157 self.assertEqual(None, giptm.full_clean()) 158 159 def test_invalid_v6_ip_raises_error(self): 160 giptm = GenericIPAddressTestModel(v6_ip="1.2.3.4") 161 self.assertFailsValidation(giptm.full_clean, ['v6_ip',]) 162 giptm = GenericIPAddressTestModel(v6_ip="1:2") 163 self.assertFailsValidation(giptm.full_clean, ['v6_ip',]) 164 165 def test_v6_uniqueness_detection(self): 166 # These two addresses are the same with different syntax 167 giptm = GenericIPAddressTestModel(generic_ip="2001::1:0:0:0:0:2") 168 giptm.save() 169 giptm = GenericIPAddressTestModel(generic_ip="2001:0:1:2") 170 self.assertFailsValidation(giptm.full_clean, ['generic_ip',]) 171 172 def test_v4_unpack_uniqueness_detection(self): 173 # These two are different, because we are not doing IPv4 unpacking 174 giptm = GenericIPAddressTestModel(generic_ip="::ffff:10.10.10.10") 175 giptm.save() 176 giptm = GenericIPAddressTestModel(generic_ip="10.10.10.10") 177 self.assertEqual(None, giptm.full_clean()) 178 179 # These two are the same, because we are doing IPv4 unpacking 180 giptm = GenericIPAddressWithUnpackUniqueTestModel(generic_v4unpack_ip="::ffff:18.52.18.52") 181 giptm.save() 182 giptm = GenericIPAddressWithUnpackUniqueTestModel(generic_v4unpack_ip="18.52.18.52") 183 self.assertFailsValidation(giptm.full_clean, ['generic_v4unpack_ip',]) 184 185 No newline at end of file -
tests/modeltests/validation/models.py
81 81 82 82 class UniqueErrorsModel(models.Model): 83 83 name = models.CharField(max_length=100, unique=True, error_messages={'unique': u'Custom unique name message.'}) 84 number = models.IntegerField(unique=True, error_messages={'unique': u'Custom unique number message.'}) 85 No newline at end of file 84 number = models.IntegerField(unique=True, error_messages={'unique': u'Custom unique number message.'}) 85 86 class GenericIPAddressTestModel(models.Model): 87 generic_ip = models.GenericIPAddressField(blank=True, unique=True) 88 v4_ip = models.GenericIPAddressField(blank=True, protocol="ipv4") 89 v6_ip = models.GenericIPAddressField(blank=True, protocol="ipv6") 90 91 class GenericIPAddressWithUnpackUniqueTestModel(models.Model): 92 generic_v4unpack_ip = models.GenericIPAddressField(blank=True, unique=True, unpack_ipv4_mapped=True) 93 94 No newline at end of file -
tests/regressiontests/forms/tests/error_messages.py
196 196 self.assertFormErrors([u'REQUIRED'], f.clean, '') 197 197 self.assertFormErrors([u'INVALID IP ADDRESS'], f.clean, '127.0.0') 198 198 199 def test_generic_ipaddressfield(self): 200 e = { 201 'required': 'REQUIRED', 202 'invalid': 'INVALID IP ADDRESS', 203 } 204 f = GenericIPAddressField(error_messages=e) 205 self.assertFormErrors([u'REQUIRED'], f.clean, '') 206 self.assertFormErrors([u'INVALID IP ADDRESS'], f.clean, '127.0.0') 207 199 208 def test_subclassing_errorlist(self): 200 209 class TestForm(Form): 201 210 first_name = CharField() -
tests/regressiontests/forms/tests/extra.py
460 460 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5') 461 461 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '256.125.1.5') 462 462 463 464 def test_generic_ipaddress_invalid_arguments(self): 465 self.assertRaises(ValueError, GenericIPAddressField, protocol="hamster") 466 self.assertRaises(ValueError, GenericIPAddressField, protocol="ipv4", unpack_ipv4_mapped=True) 467 468 def test_generic_ipaddress_as_generic(self): 469 # The edges of the IPv6 validation code are not deeply tested here, 470 # they are covered in the tests for django.utils.ipv6 471 472 f = GenericIPAddressField() 473 self.assertFormErrors([u'This field is required.'], f.clean, '') 474 self.assertFormErrors([u'This field is required.'], f.clean, None) 475 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 476 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo') 477 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '127.0.0.') 478 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1.2.3.4.5') 479 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5') 480 self.assertEqual(f.clean('fe80::223:6cff:fe8a:2e8a'), u'fe80::223:6cff:fe8a:2e8a') 481 self.assertEqual(f.clean('2a02::223:6cff:fe8a:2e8a'), u'2a02::223:6cff:fe8a:2e8a') 482 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '12345:2:3:4') 483 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3::4') 484 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a') 485 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8') 486 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1:2') 487 488 def test_generic_ipaddress_as_ipv4_only(self): 489 f = GenericIPAddressField(protocol="IPv4") 490 self.assertFormErrors([u'This field is required.'], f.clean, '') 491 self.assertFormErrors([u'This field is required.'], f.clean, None) 492 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 493 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, 'foo') 494 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '127.0.0.') 495 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5') 496 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '256.125.1.5') 497 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, 'fe80::223:6cff:fe8a:2e8a') 498 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '2a02::223:6cff:fe8a:2e8a') 499 500 def test_generic_ipaddress_as_ipv4_only(self): 501 f = GenericIPAddressField(protocol="IPv6") 502 self.assertFormErrors([u'This field is required.'], f.clean, '') 503 self.assertFormErrors([u'This field is required.'], f.clean, None) 504 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '127.0.0.1') 505 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, 'foo') 506 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '127.0.0.') 507 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '1.2.3.4.5') 508 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '256.125.1.5') 509 self.assertEqual(f.clean('fe80::223:6cff:fe8a:2e8a'), u'fe80::223:6cff:fe8a:2e8a') 510 self.assertEqual(f.clean('2a02::223:6cff:fe8a:2e8a'), u'2a02::223:6cff:fe8a:2e8a') 511 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '12345:2:3:4') 512 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '1::2:3::4') 513 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a') 514 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8') 515 self.assertFormErrors([u'Enter a valid IPv6 address.'], f.clean, '1:2') 516 517 def test_generic_ipaddress_as_generic_not_required(self): 518 f = GenericIPAddressField(required=False) 519 self.assertEqual(f.clean(''), u'') 520 self.assertEqual(f.clean(None), u'') 521 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 522 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo') 523 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '127.0.0.') 524 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1.2.3.4.5') 525 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5') 526 self.assertEqual(f.clean('fe80::223:6cff:fe8a:2e8a'), u'fe80::223:6cff:fe8a:2e8a') 527 self.assertEqual(f.clean('2a02::223:6cff:fe8a:2e8a'), u'2a02::223:6cff:fe8a:2e8a') 528 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '12345:2:3:4') 529 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3::4') 530 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a') 531 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8') 532 self.assertFormErrors([u'Enter a valid IPv4 or IPv6 address.'], f.clean, '1:2') 533 534 def test_generic_ipaddress_normalisation(self): 535 # Test the normalising code 536 f = GenericIPAddressField() 537 self.assertEqual(f.clean('::ffff:0a0a:0a0a'), u'::ffff:10.10.10.10') 538 self.assertEqual(f.clean('::ffff:10.10.10.10'), u'::ffff:10.10.10.10') 539 self.assertEqual(f.clean('2001:000:a:0000:0:fe:fe:beef'), u'2001:0:a::fe:fe:beef') 540 self.assertEqual(f.clean('2001::a:0000:0:fe:fe:beef'), u'2001:0:a::fe:fe:beef') 541 542 f = GenericIPAddressField(unpack_ipv4_mapped=True) 543 self.assertEqual(f.clean('::ffff:0a0a:0a0a'), u'10.10.10.10') 544 545 463 546 def test_smart_unicode(self): 464 547 class Test: 465 548 def __str__(self): -
tests/regressiontests/serializers_regress/tests.py
196 196 #(XX, ImageData 197 197 (data_obj, 90, IPAddressData, "127.0.0.1"), 198 198 (data_obj, 91, IPAddressData, None), 199 (data_obj, 95, GenericIPAddressData, "fe80:1424:2223:6cff:fe8a:2e8a:2151:abcd"), 200 (data_obj, 96, GenericIPAddressData, None), 199 201 (data_obj, 100, NullBooleanData, True), 200 202 (data_obj, 101, NullBooleanData, False), 201 203 (data_obj, 102, NullBooleanData, None), … … 298 300 (pk_obj, 682, IntegerPKData, 0), 299 301 # (XX, ImagePKData 300 302 (pk_obj, 690, IPAddressPKData, "127.0.0.1"), 303 (pk_obj, 695, GenericIPAddressPKData, "fe80:1424:2223:6cff:fe8a:2e8a:2151:abcd"), 301 304 # (pk_obj, 700, NullBooleanPKData, True), 302 305 # (pk_obj, 701, NullBooleanPKData, False), 303 306 (pk_obj, 710, PhonePKData, "212-634-5789"), -
tests/regressiontests/serializers_regress/models.py
52 52 class IPAddressData(models.Model): 53 53 data = models.IPAddressField(null=True) 54 54 55 class GenericIPAddressData(models.Model): 56 data = models.GenericIPAddressField(null=True) 57 55 58 class NullBooleanData(models.Model): 56 59 data = models.NullBooleanField(null=True) 57 60 … … 187 190 class IPAddressPKData(models.Model): 188 191 data = models.IPAddressField(primary_key=True) 189 192 193 class GenericIPAddressPKData(models.Model): 194 data = models.GenericIPAddressField(primary_key=True) 195 190 196 # This is just a Boolean field with null=True, and we can't test a PK value of NULL. 191 197 # class NullBooleanPKData(models.Model): 192 198 # data = models.NullBooleanField(primary_key=True) -
tests/regressiontests/utils/tests.py
19 19 from datetime_safe import * 20 20 from baseconv import * 21 21 from jslex import * 22 from ipv6 import *