mirror of
https://github.com/django/django.git
synced 2025-07-06 18:59:13 +00:00
[soc2009/model-validation] validators refactoring
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11457 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
05524abf1b
commit
9578491379
@ -14,14 +14,6 @@ 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):
|
||||
regex = ''
|
||||
message = _(u'Enter a valid value.')
|
||||
@ -46,7 +38,13 @@ class RegexValidator(object):
|
||||
raise ValidationError(self.message, code=self.code)
|
||||
|
||||
class URLValidator(RegexValidator):
|
||||
regex = url_re
|
||||
regex = 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)
|
||||
|
||||
def __init__(self, verify_exists=False, validator_user_agent=URL_VALIDATOR_USER_AGENT):
|
||||
super(URLValidator, self).__init__()
|
||||
@ -72,97 +70,70 @@ class URLValidator(RegexValidator):
|
||||
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)
|
||||
except (ValueError, TypeError), e:
|
||||
raise ValidationError('')
|
||||
|
||||
|
||||
email_re = re.compile(
|
||||
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
|
||||
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
|
||||
r')@(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
|
||||
|
||||
def validate_email(value):
|
||||
if not email_re.search(smart_unicode(value)):
|
||||
raise ValidationError(_(u'Enter a valid e-mail address.'), code='invalid')
|
||||
validate_email = RegexValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')
|
||||
|
||||
slug_re = re.compile(r'^[-\w]+$')
|
||||
|
||||
def validate_slug(value):
|
||||
if not slug_re.search(smart_unicode(value)):
|
||||
raise ValidationError(
|
||||
_(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."),
|
||||
code='invalid'
|
||||
)
|
||||
validate_slug = RegexValidator(slug_re, _(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
|
||||
|
||||
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}$')
|
||||
|
||||
def validate_ipv4_address(value):
|
||||
if not ipv4_re.search(smart_unicode(value)):
|
||||
raise ValidationError(
|
||||
_(u'Enter a valid IPv4 address.'),
|
||||
code="invalid"
|
||||
)
|
||||
validate_ipv4_address = RegexValidator(ipv4_re, _(u'Enter a valid IPv4 address.'), 'invalid')
|
||||
|
||||
comma_separated_int_list_re = re.compile('^[\d,]+$')
|
||||
validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _(u'Enter only digits separated by commas.'), 'invalid')
|
||||
|
||||
def validate_comma_separated_integer_list(value):
|
||||
if not comma_separated_int_list_re.search(smart_unicode(value)):
|
||||
raise ValidationError(
|
||||
_(u'Enter only digits separated by commas.'),
|
||||
code="invalid"
|
||||
)
|
||||
|
||||
class MaxValueValidator(object):
|
||||
def __init__(self, max_value):
|
||||
self.max_value = max_value
|
||||
class BaseValidator(object):
|
||||
compare = lambda self, a, b: a is b
|
||||
clean = lambda self, x: x
|
||||
message = _(u'Ensure this value is %(limit_value)s (it is %(show_value)s).')
|
||||
code = 'limit_value'
|
||||
|
||||
def __init__(self, limit_value):
|
||||
self.limit_value = limit_value
|
||||
|
||||
def __call__(self, value):
|
||||
if value > self.max_value:
|
||||
cleaned = self.clean(value)
|
||||
if self.compare(cleaned, self.limit_value):
|
||||
raise ValidationError(
|
||||
_(u'Ensure this value is less than or equal to %s.') % self.max_value,
|
||||
code='max_value',
|
||||
params=(self.max_value,)
|
||||
self.message,
|
||||
code=self.code,
|
||||
params={'limit_value': self.limit_value, 'show_value': cleaned}
|
||||
)
|
||||
|
||||
class MinValueValidator(object):
|
||||
def __init__(self, min_value):
|
||||
self.min_value = min_value
|
||||
class MaxValueValidator(BaseValidator):
|
||||
compare = lambda self, a, b: a > b
|
||||
message = _(u'Ensure this value is less than or equal to %(limit_value)s.')
|
||||
code = 'max_value'
|
||||
|
||||
def __call__(self, value):
|
||||
if value < self.min_value:
|
||||
raise ValidationError(
|
||||
_(u'Ensure this value is greater than or equal to %s.') % self.min_value,
|
||||
code='min_value',
|
||||
params=(self.min_value,)
|
||||
)
|
||||
class MinValueValidator(BaseValidator):
|
||||
compare = lambda self, a, b: a < b
|
||||
message = _(u'Ensure this value is greater than or equal to %(limit_value)s.')
|
||||
code = 'min_value'
|
||||
|
||||
class MinLengthValidator(object):
|
||||
def __init__(self, min_length):
|
||||
self.min_length = min_length
|
||||
class MinLengthValidator(BaseValidator):
|
||||
compare = lambda self, a, b: a < b
|
||||
clean = lambda self, x: len(x)
|
||||
message = _(u'Ensure this value has at least %(limit_value)d characters (it has %(show_value)d).')
|
||||
code = 'min_length'
|
||||
|
||||
def __call__(self, value):
|
||||
value_len = len(value)
|
||||
if value_len < self.min_length:
|
||||
raise ValidationError(
|
||||
_(u'Ensure this value has at least %(min)d characters (it has %(length)d).'),
|
||||
code='min_length',
|
||||
params={ 'min': self.min_length, 'length': value_len}
|
||||
)
|
||||
class MaxLengthValidator(BaseValidator):
|
||||
compare = lambda self, a, b: a > b
|
||||
clean = lambda self, x: len(x)
|
||||
message = _(u'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).')
|
||||
code = 'max_length'
|
||||
|
||||
class MaxLengthValidator(object):
|
||||
def __init__(self, max_length):
|
||||
self.max_length = max_length
|
||||
|
||||
def __call__(self, value):
|
||||
value_len = len(value)
|
||||
if value_len > self.max_length:
|
||||
raise ValidationError(
|
||||
_(u'Ensure this value has at most %(max)d characters (it has %(length)d).'),
|
||||
code='max_length',
|
||||
params={ 'max': self.max_length, 'length': value_len}
|
||||
)
|
||||
|
||||
class ComplexValidator(object):
|
||||
def get_value(self, name, all_values, obj):
|
||||
@ -185,3 +156,4 @@ class RequiredIfOtherFieldBlank(ComplexValidator):
|
||||
if self.get_value(self.other_field, all_values, obj) in EMPTY_VALUES:
|
||||
if value in EMPTY_VALUES:
|
||||
raise ValidationError('This field is required if %s is blank.' % self.other_field)
|
||||
|
||||
|
@ -204,8 +204,8 @@ class CharField(Field):
|
||||
class IntegerField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Enter a whole number.'),
|
||||
'max_value': _(u'Ensure this value is less than or equal to %s.'),
|
||||
'min_value': _(u'Ensure this value is greater than or equal to %s.'),
|
||||
'max_value': _(u'Ensure this value is less than or equal to %(limit_value)s.'),
|
||||
'min_value': _(u'Ensure this value is greater than or equal to %(limit_value)s.'),
|
||||
}
|
||||
|
||||
def __init__(self, max_value=None, min_value=None, *args, **kwargs):
|
||||
@ -254,8 +254,8 @@ class FloatField(IntegerField):
|
||||
class DecimalField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Enter a number.'),
|
||||
'max_value': _(u'Ensure this value is less than or equal to %s.'),
|
||||
'min_value': _(u'Ensure this value is greater than or equal to %s.'),
|
||||
'max_value': _(u'Ensure this value is less than or equal to %(limit_value)s.'),
|
||||
'min_value': _(u'Ensure this value is greater than or equal to %(limit_value)s.'),
|
||||
'max_digits': _('Ensure that there are no more than %s digits in total.'),
|
||||
'max_decimal_places': _('Ensure that there are no more than %s decimal places.'),
|
||||
'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.')
|
||||
|
@ -26,8 +26,8 @@ ValidationError: [u'LENGTH 11, MAX LENGTH 10']
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %(limit_value)s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %(limit_value)s'
|
||||
>>> f = IntegerField(min_value=5, max_value=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
@ -50,8 +50,8 @@ ValidationError: [u'MAX VALUE IS 10']
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %(limit_value)s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %(limit_value)s'
|
||||
>>> f = FloatField(min_value=5, max_value=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
@ -74,8 +74,8 @@ ValidationError: [u'MAX VALUE IS 10']
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %(limit_value)s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %(limit_value)s'
|
||||
>>> e['max_digits'] = 'MAX DIGITS IS %s'
|
||||
>>> e['max_decimal_places'] = 'MAX DP IS %s'
|
||||
>>> e['max_whole_digits'] = 'MAX DIGITS BEFORE DP IS %s'
|
||||
|
Loading…
x
Reference in New Issue
Block a user