Ticket #811: ipv6-14734.diff
File ipv6-14734.diff, 17.0 KB (added by , 14 years ago) |
---|
-
django/db/models/fields/__init__.py
913 913 class IPAddressField(Field): 914 914 empty_strings_allowed = False 915 915 description = _("IP address") 916 def __init__(self, *args, **kwargs): 917 kwargs['max_length'] = 15 916 def __init__(self, allowv4=True, allowv6=False, *args, **kwargs): 917 assert allowv4 or allowv6, "%ss must have allowv4=True and/or allowv6=True." % self.__class__.__name__ 918 self.allowv4, self.allowv6 = allowv4, allowv6 919 if allowv6: 920 kwargs['max_length'] = 39 921 else: 922 kwargs['max_length'] = 15 918 923 Field.__init__(self, *args, **kwargs) 919 924 920 925 def get_internal_type(self): 921 926 return "IPAddressField" 922 927 923 928 def formfield(self, **kwargs): 924 defaults = {'form_class': forms.IPAddressField} 929 defaults = {'form_class': forms.IPAddressField, 930 'allowv4': self.allowv4, 931 'allowv6': self.allowv6} 925 932 defaults.update(kwargs) 926 933 return super(IPAddressField, self).formfield(**defaults) 927 934 -
django/db/backends/sqlite3/creation.py
19 19 'FloatField': 'real', 20 20 'IntegerField': 'integer', 21 21 'BigIntegerField': 'bigint', 22 'IPAddressField': 'char( 15)',22 'IPAddressField': 'char(%(max_length)s)', 23 23 'NullBooleanField': 'bool', 24 24 'OneToOneField': 'integer', 25 25 'PositiveIntegerField': 'integer unsigned', -
django/db/backends/mysql/creation.py
18 18 'FloatField': 'double precision', 19 19 'IntegerField': 'integer', 20 20 'BigIntegerField': 'bigint', 21 'IPAddressField': 'char( 15)',21 'IPAddressField': 'char(%(max_length)s)', 22 22 'NullBooleanField': 'bool', 23 23 'OneToOneField': 'integer', 24 24 'PositiveIntegerField': 'integer UNSIGNED', -
django/db/backends/oracle/creation.py
26 26 'FloatField': 'DOUBLE PRECISION', 27 27 'IntegerField': 'NUMBER(11)', 28 28 'BigIntegerField': 'NUMBER(19)', 29 'IPAddressField': 'VARCHAR2( 15)',29 'IPAddressField': 'VARCHAR2(%(max_length)s)', 30 30 'NullBooleanField': 'NUMBER(1) CHECK ((%(qn_column)s IN (0,1)) OR (%(qn_column)s IS NULL))', 31 31 'OneToOneField': 'NUMBER(11)', 32 32 'PositiveIntegerField': 'NUMBER(11) CHECK (%(qn_column)s >= 0)', -
django/forms/fields.py
919 919 920 920 921 921 class IPAddressField(CharField): 922 def __init__(self, allowv4=True, allowv6=False, *args, **kwargs): 923 self.allowv4, self.allowv6 = allowv4, allowv6 924 super(IPAddressField, self).__init__(*args, **kwargs) 925 if allowv4 and allowv6: 926 self.validators.append(validators.validate_ip_address) 927 elif allowv4: 928 self.validators.append(validators.validate_ipv4_address) 929 elif allowv6: 930 self.validators.append(validators.validate_ipv6_address) 922 931 default_error_messages = { 923 'invalid': _(u'Enter a valid IP v4address.'),932 'invalid': _(u'Enter a valid IP address.'), 924 933 } 925 default_validators = [validators.validate_ipv4_address]926 934 927 935 928 936 class SlugField(CharField): -
django/core/validators.py
4 4 from django.core.exceptions import ValidationError 5 5 from django.utils.translation import ugettext_lazy as _ 6 6 from django.utils.encoding import smart_unicode 7 from django.utils.ip import ipv6_normalize 7 8 8 9 # These values, if given to validate(), will trigger the self.required check. 9 10 EMPTY_VALUES = (None, '', [], (), {}) … … 19 20 regex = '' 20 21 message = _(u'Enter a valid value.') 21 22 code = 'invalid' 23 normalizer = None 22 24 23 def __init__(self, regex=None, message=None, code=None ):25 def __init__(self, regex=None, message=None, code=None, normalizer=None): 24 26 if regex is not None: 25 27 self.regex = regex 26 28 if message is not None: 27 29 self.message = message 28 30 if code is not None: 29 31 self.code = code 32 if normalizer is not None: 33 self.normalizer = normalizer 30 34 31 35 if isinstance(self.regex, basestring): 32 36 self.regex = re.compile(regex) … … 35 39 """ 36 40 Validates that the input matches the regular expression. 37 41 """ 42 if self.normalizer: 43 try: 44 value = self.normalizer(value) 45 except ValueError: 46 raise ValidationError(self.message, code=self.code) 47 38 48 if not self.regex.search(smart_unicode(value)): 39 49 raise ValidationError(self.message, code=self.code) 40 50 … … 125 135 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}$') 126 136 validate_ipv4_address = RegexValidator(ipv4_re, _(u'Enter a valid IPv4 address.'), 'invalid') 127 137 138 ipv6_re = re.compile(r'^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$') 139 validate_ipv6_address = RegexValidator(ipv6_re, _(u'Enter a valid IPv6 address.'), 'invalid', ipv6_normalize) 140 141 def validate_ip_address(value): 142 try: 143 validate_ipv4_address(value) 144 except ValidationError: 145 try: 146 validate_ipv6_address(value) 147 except ValidationError: 148 raise ValidationError(_(u'Enter a valid IP address.'), code='invalid') 149 128 150 comma_separated_int_list_re = re.compile('^[\d,]+$') 129 151 validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _(u'Enter only digits separated by commas.'), 'invalid') 130 152 -
django/utils/ip.py
1 def ipv6_normalize(addr): 2 """ 3 Normalize an IPv6 address to allow easy regexp validation. 4 Mostly checks the length, and gets rid of tricky things 5 like IPv4 mapped addresses and :: shortcuts 6 7 Outputs a string 8 """ 9 # Some basic error checking 10 if addr.count('::') > 2 or ':::' in addr: 11 raise ValueError 12 13 ip = addr.split(':') 14 nbfull = len([elem for elem in ip if elem != '']) 15 nb = len(ip) 16 17 if nb < 3: 18 # The minimal IPv6 address is :: so at least 3 parts after split 19 raise ValueError 20 21 if nbfull >= 1 and '.' in ip[-1]: 22 # Convert IPv4 mapped addresses to full hexadecimal notation 23 ipv4 = ip[-1].split('.') 24 hex1 = (int(ipv4[0]) << 8) + int(ipv4[1]) 25 hex2 = (int(ipv4[2]) << 8) + int(ipv4[3]) 26 ip[-1:] = [hex(hex1)[2:], hex(hex2)[2:]] 27 nbfull = nbfull + 1 28 nb = nb + 1 29 30 if nbfull == 8 or nbfull == nb: 31 # No need to bother 32 return addr 33 elif nbfull > 8: 34 # Has to be invalid anyway 35 raise ValueError 36 37 # Begin normalization 38 start, end, index = (None, None, 0) 39 for elem in ip: 40 if elem == '': 41 if start is None: 42 start = index 43 end = index 44 else: 45 end = index 46 index += 1 47 pad = 8 - nbfull 48 if end != start: 49 ip[start:end-start+1] = ['0'] * pad 50 else: 51 ip[start] = '0' 52 if pad > 1: 53 ip[start:1] = ['0'] * (pad - 1) 54 return ':'.join([item for item in ip if len(item) > 0]) -
tests/regressiontests/forms/tests/error_messages.py
Property changes on: django/utils/ip.py ___________________________________________________________________ Added: svn:mime-type + text/plain
192 192 'required': 'REQUIRED', 193 193 'invalid': 'INVALID IP ADDRESS', 194 194 } 195 f = IPAddressField(error_messages=e )195 f = IPAddressField(error_messages=e, allowv4=True, allowv6=True) 196 196 self.assertFormErrors([u'REQUIRED'], f.clean, '') 197 197 self.assertFormErrors([u'INVALID IP ADDRESS'], f.clean, '127.0.0') 198 198 -
tests/regressiontests/forms/tests/extra.py
437 437 self.assertEqual(f.cleaned_data['field1'], u'some text,JP,2007-04-25 06:24:00') 438 438 439 439 def test_ipaddress(self): 440 f = IPAddressField( )440 f = IPAddressField(allowv4=True, allowv6=False) 441 441 self.assertFormErrors([u'This field is required.'], f.clean, '') 442 442 self.assertFormErrors([u'This field is required.'], f.clean, None) 443 443 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 444 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, 'foo') 445 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '127.0.0.') 446 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5') 447 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '256.125.1.5') 444 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '::1') 445 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, 'foo') 446 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.') 447 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1.2.3.4.5') 448 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '256.125.1.5') 449 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7') 450 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7:8:9') 448 451 449 f = IPAddressField(required=False) 452 f = IPAddressField(allowv4=False, allowv6=True) 453 self.assertFormErrors([u'This field is required.'], f.clean, '') 454 self.assertFormErrors([u'This field is required.'], f.clean, None) 455 self.assertEqual(f.clean('::1'), u'::1') 456 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.1') 457 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, 'foo') 458 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.') 459 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1.2.3.4.5') 460 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '256.125.1.5') 461 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7') 462 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7:8:9') 463 464 f = IPAddressField(allowv4=True, allowv6=True) 465 self.assertFormErrors([u'This field is required.'], f.clean, '') 466 self.assertFormErrors([u'This field is required.'], f.clean, None) 467 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 468 self.assertEqual(f.clean('::1'), u'::1') 469 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, 'foo') 470 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.') 471 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1.2.3.4.5') 472 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '256.125.1.5') 473 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7') 474 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7:8:9') 475 476 f = IPAddressField(required=False, allowv4=True, allowv6=False) 450 477 self.assertEqual(f.clean(''), u'') 451 478 self.assertEqual(f.clean(None), u'') 452 479 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 453 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, 'foo') 454 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '127.0.0.') 455 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5') 456 self.assertFormErrors([u'Enter a valid IPv4 address.'], f.clean, '256.125.1.5') 480 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '::1') 481 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, 'foo') 482 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.') 483 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1.2.3.4.5') 484 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '256.125.1.5') 485 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7') 486 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7:8:9') 457 487 488 f = IPAddressField(required=False, allowv4=False, allowv6=True) 489 self.assertEqual(f.clean(''), u'') 490 self.assertEqual(f.clean(None), u'') 491 self.assertEqual(f.clean('::1'), u'::1') 492 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.1') 493 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, 'foo') 494 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.') 495 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1.2.3.4.5') 496 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '256.125.1.5') 497 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7') 498 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7:8:9') 499 500 f = IPAddressField(required=False, allowv4=True, allowv6=True) 501 self.assertEqual(f.clean(''), u'') 502 self.assertEqual(f.clean(None), u'') 503 self.assertEqual(f.clean('127.0.0.1'), u'127.0.0.1') 504 self.assertEqual(f.clean('::1'), u'::1') 505 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, 'foo') 506 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '127.0.0.') 507 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1.2.3.4.5') 508 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '256.125.1.5') 509 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7') 510 self.assertFormErrors([u'Enter a valid IP address.'], f.clean, '1:2:3:4:5:6:7:8:9') 511 458 512 def test_smart_unicode(self): 459 513 class Test: 460 514 def __str__(self): -
tests/regressiontests/serializers_regress/tests.py
195 195 #(XX, ImageData 196 196 (data_obj, 90, IPAddressData, "127.0.0.1"), 197 197 (data_obj, 91, IPAddressData, None), 198 (data_obj, 92, IPAddressData, "::1"), 198 199 (data_obj, 100, NullBooleanData, True), 199 200 (data_obj, 101, NullBooleanData, False), 200 201 (data_obj, 102, NullBooleanData, None), … … 300 301 (pk_obj, 682, IntegerPKData, 0), 301 302 # (XX, ImagePKData 302 303 (pk_obj, 690, IPAddressPKData, "127.0.0.1"), 304 (pk_obj, 691, IPAddressPKData, "::1"), 303 305 # (pk_obj, 700, NullBooleanPKData, True), 304 306 # (pk_obj, 701, NullBooleanPKData, False), 305 307 (pk_obj, 710, PhonePKData, "212-634-5789"), -
tests/regressiontests/serializers_regress/models.py
50 50 # data = models.ImageField(null=True) 51 51 52 52 class IPAddressData(models.Model): 53 data = models.IPAddressField(null=True )53 data = models.IPAddressField(null=True, allowv4=True, allowv6=True) 54 54 55 55 class NullBooleanData(models.Model): 56 56 data = models.NullBooleanField(null=True) … … 188 188 # data = models.ImageField(primary_key=True) 189 189 190 190 class IPAddressPKData(models.Model): 191 data = models.IPAddressField(primary_key=True )191 data = models.IPAddressField(primary_key=True, allowv4=True, allowv6=True) 192 192 193 193 # This is just a Boolean field with null=True, and we can't test a PK value of NULL. 194 194 # class NullBooleanPKData(models.Model):