diff options
author | Honza Král <honza.kral@gmail.com> | 2009-08-15 13:33:38 +0000 |
---|---|---|
committer | Honza Král <honza.kral@gmail.com> | 2009-08-15 13:33:38 +0000 |
commit | 84c9cf16d36661f891673208ef8517881167881e (patch) | |
tree | c95991329f15883a0f82e42e1eda02a7add9ca8a | |
parent | 69fef1daef3ce5a34bd7701f0f23765da5c926e6 (diff) | |
download | django-84c9cf16d36661f891673208ef8517881167881e.tar.gz |
[soc2009/model-validation] validate url logic moved to validators
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11454 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r-- | django/core/validators.py | 48 | ||||
-rw-r--r-- | django/forms/fields.py | 46 |
2 files changed, 52 insertions, 42 deletions
diff --git a/django/core/validators.py b/django/core/validators.py index 3716cb4898..09258f7e3e 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -7,6 +7,54 @@ from django.utils.encoding import smart_unicode # These values, if given to validate(), will trigger the self.required check. EMPTY_VALUES = (None, '', [], (), {}) +try: + from django.conf import settings + URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT +except ImportError: + # It's OK if Django settings aren't configured. + URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)' + +url_re = re.compile( + r'^https?://' # http:// or https:// + r'(?:(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}|' #domain... + r'localhost|' #localhost... + r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip + r'(?::\d+)?' # optional port + r'(?:/?|/\S+)$', re.IGNORECASE) + +class RegexValidator(object): + def __call__(self, value): + """ + Validates that the input matches the regular expression. + """ + if not self.regex.search(smart_unicode(value)): + raise ValidationError(_(u'Enter a valid value.'), code='invalid') + +class URLValidator(RegexValidator): + def __init__(self, regex=url_re, verify_exists=False, validator_user_agent=URL_VALIDATOR_USER_AGENT): + self.regex = regex + self.verify_exists = verify_exists + self.user_agent = validator_user_agent + + def __call__(self, value): + super(URLValidator, self).__call__(value) + if self.verify_exists: + import urllib2 + headers = { + "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Connection": "close", + "User-Agent": self.user_agent, + } + try: + req = urllib2.Request(value, None, headers) + u = urllib2.urlopen(req) + except ValueError: + raise ValidationError(_(u'Enter a valid URL.'), code='invalid') + except: # urllib2.URLError, httplib.InvalidURL, etc. + raise ValidationError(_(u'This URL appears to be a broken link.'), code='invalid_link') + def validate_integer(value): try: int(value) diff --git a/django/forms/fields.py b/django/forms/fields.py index d8f3e1477c..8bf1df3f58 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -457,14 +457,6 @@ class EmailField(CharField): } default_validators = [validators.validate_email] -try: - from django.conf import settings - URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT -except ImportError: - # It's OK if Django settings aren't configured. - URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)' - - class FileField(Field): widget = FileInput default_error_messages = { @@ -556,26 +548,17 @@ class ImageField(FileField): f.seek(0) return f -url_re = re.compile( - r'^https?://' # http:// or https:// - r'(?:(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}|' #domain... - r'localhost|' #localhost... - r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip - r'(?::\d+)?' # optional port - r'(?:/?|/\S+)$', re.IGNORECASE) - -class URLField(RegexField): +class URLField(CharField): default_error_messages = { 'invalid': _(u'Enter a valid URL.'), 'invalid_link': _(u'This URL appears to be a broken link.'), } def __init__(self, max_length=None, min_length=None, verify_exists=False, - validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs): - super(URLField, self).__init__(url_re, max_length, min_length, *args, + validator_user_agent=validators.URL_VALIDATOR_USER_AGENT, *args, **kwargs): + super(URLField, self).__init__(max_length, min_length, *args, **kwargs) - self.verify_exists = verify_exists - self.user_agent = validator_user_agent + self.validators.append(validators.URLValidator(verify_exists=verify_exists, validator_user_agent=validator_user_agent)) def to_python(self, value): # If no URL scheme given, assume http:// @@ -586,27 +569,6 @@ class URLField(RegexField): value += '/' return super(URLField, self).to_python(value) - def validate(self, value): - super(URLField, self).validate(value) - if value == u'': - return value - if self.verify_exists: - import urllib2 - headers = { - "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", - "Accept-Language": "en-us,en;q=0.5", - "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Connection": "close", - "User-Agent": self.user_agent, - } - try: - req = urllib2.Request(value, None, headers) - u = urllib2.urlopen(req) - except ValueError: - raise ValidationError(self.error_messages['invalid']) - except: # urllib2.URLError, httplib.InvalidURL, etc. - raise ValidationError(self.error_messages['invalid_link']) - class BooleanField(Field): widget = CheckboxInput |