Ticket #9764: idn_support_02.diff
File idn_support_02.diff, 7.6 KB (added by , 15 years ago) |
---|
-
django/db/models/fields/__init__.py
807 807 return super(DecimalField, self).formfield(**defaults) 808 808 809 809 class EmailField(CharField): 810 default_validators = [validators. validate_email]810 default_validators = [validators.EmailValidator()] 811 811 description = _("E-mail address") 812 812 813 813 def __init__(self, *args, **kwargs): -
django/forms/fields.py
413 413 default_error_messages = { 414 414 'invalid': _(u'Enter a valid e-mail address.'), 415 415 } 416 default_validators = [validators. validate_email]416 default_validators = [validators.EmailValidator()] 417 417 418 418 class FileField(Field): 419 419 widget = FileInput -
django/core/validators.py
1 1 import re 2 import urlparse 2 3 3 4 from django.core.exceptions import ValidationError 4 5 from django.utils.translation import ugettext_lazy as _ … … 52 53 self.user_agent = validator_user_agent 53 54 54 55 def __call__(self, value): 55 super(URLValidator, self).__call__(value) 56 try: 57 super(URLValidator, self).__call__(value) 58 except ValidationError, e: 59 # Trivial case failed. Try for possible IDN domain 60 if value: 61 original = value 62 value = smart_unicode(value) 63 splitted = urlparse.urlsplit(value) 64 try: 65 netloc_ace = splitted[1].encode('idna') # IDN -> ACE 66 except UnicodeError: # invalid domain part 67 raise e 68 value = value.replace(splitted[1], netloc_ace) 69 # If no URL path given, assume / 70 if not splitted[2]: 71 value += u'/' 72 super(URLValidator, self).__call__(value) 73 # After validation revert ACE encoded domain-part to 74 # original (IDN) value as suggested by RFC 3490 75 value = original 76 else: 77 raise 78 56 79 if self.verify_exists: 57 80 import urllib2 58 81 headers = { … … 77 100 except (ValueError, TypeError), e: 78 101 raise ValidationError('') 79 102 103 class EmailValidator(RegexValidator): 104 regex = re.compile( 105 r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom 106 r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string 107 r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain 108 message = _(u'Enter a valid e-mail address.') 80 109 81 email_re = re.compile( 82 r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom 83 r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string 84 r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain 85 validate_email = RegexValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid') 110 def __call__(self, value): 111 try: 112 super(EmailValidator, self).__call__(value) 113 except ValidationError, e: 114 # Trivial case failed. Try for possible IDN domain-part 115 if value and u'@' in value: 116 parts = value.split(u'@') 117 domain_part = parts[-1] 118 try: 119 parts[-1] = parts[-1].encode('idna') 120 except UnicodeError: 121 raise e 122 super(EmailValidator, self).__call__(u'@'.join(parts)) 123 else: 124 raise 86 125 126 validate_email = EmailValidator() 127 87 128 slug_re = re.compile(r'^[-\w]+$') 88 129 validate_slug = RegexValidator(slug_re, _(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid') 89 130 -
tests/regressiontests/forms/fields.py
408 408 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@inv-.-alid.com') 409 409 self.assertEqual(u'example@valid-----hyphens.com', f.clean('example@valid-----hyphens.com')) 410 410 self.assertEqual(u'example@valid-with-hyphens.com', f.clean('example@valid-with-hyphens.com')) 411 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'example@.com') 412 self.assertEqual(u'local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com', f.clean('local@domain.with.idn.xyzäöüßabc.part.com')) 411 413 412 414 def test_email_regexp_for_performance(self): 413 415 f = EmailField() … … 489 491 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.alid-.com') 490 492 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.-alid.com') 491 493 self.assertEqual(u'http://valid-----hyphens.com/', f.clean('http://valid-----hyphens.com')) 494 self.assertEqual(u'http://some.idn.xyz\xe4\xf6\xfc\xdfabc.domain.com:123/blah', f.clean('http://some.idn.xyzäöüßabc.domain.com:123/blah')) 492 495 493 496 def test_url_regex_ticket11198(self): 494 497 f = URLField() -
docs/ref/forms/fields.txt
482 482 If provided, these arguments ensure that the string is at most or at least the 483 483 given length. 484 484 485 .. versionchanged:: 1.2 486 The EmailField previously did not recognize e-mail addresses as valid that 487 contained an IDN (Internationalized Domain Name; a domain containing 488 unicode characters) domain part. This has now been corrected. 489 485 490 ``FileField`` 486 491 ~~~~~~~~~~~~~ 487 492 … … 707 712 String used as the user-agent used when checking for a URL's existence. 708 713 Defaults to the value of the ``URL_VALIDATOR_USER_AGENT`` setting. 709 714 715 .. versionchanged:: 1.2 716 The URLField previously did not recognize URLs as valid that contained an IDN 717 (Internationalized Domain Name; a domain name containing unicode characters) 718 domain name. This has now been corrected. 719 720 710 721 Slightly complex built-in ``Field`` classes 711 722 ------------------------------------------- 712 723 -
docs/ref/forms/validation.txt
186 186 default_error_messages = { 187 187 'invalid': _(u'Enter a valid e-mail address.'), 188 188 } 189 default_validators = [validators. validate_email]189 default_validators = [validators.EMailValidator()] 190 190 191 191 As you can see, ``EmailField`` is just a ``CharField`` with customized error 192 192 message and a validator that validates e-mail addresses. This can also be done … … 196 196 197 197 is equivalent to:: 198 198 199 email = forms.CharField(validators=[validators. validate_email],199 email = forms.CharField(validators=[validators.EMailValidator()], 200 200 error_messages={'invalid': _(u'Enter a valid e-mail address.')}) 201 201 202 202