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.
|
# It's OK if Django settings aren't configured.
|
||||||
URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
|
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):
|
class RegexValidator(object):
|
||||||
regex = ''
|
regex = ''
|
||||||
message = _(u'Enter a valid value.')
|
message = _(u'Enter a valid value.')
|
||||||
@ -46,7 +38,13 @@ class RegexValidator(object):
|
|||||||
raise ValidationError(self.message, code=self.code)
|
raise ValidationError(self.message, code=self.code)
|
||||||
|
|
||||||
class URLValidator(RegexValidator):
|
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):
|
def __init__(self, verify_exists=False, validator_user_agent=URL_VALIDATOR_USER_AGENT):
|
||||||
super(URLValidator, self).__init__()
|
super(URLValidator, self).__init__()
|
||||||
@ -72,97 +70,70 @@ class URLValidator(RegexValidator):
|
|||||||
except: # urllib2.URLError, httplib.InvalidURL, etc.
|
except: # urllib2.URLError, httplib.InvalidURL, etc.
|
||||||
raise ValidationError(_(u'This URL appears to be a broken link.'), code='invalid_link')
|
raise ValidationError(_(u'This URL appears to be a broken link.'), code='invalid_link')
|
||||||
|
|
||||||
|
|
||||||
def validate_integer(value):
|
def validate_integer(value):
|
||||||
try:
|
try:
|
||||||
int(value)
|
int(value)
|
||||||
except (ValueError, TypeError), e:
|
except (ValueError, TypeError), e:
|
||||||
raise ValidationError('')
|
raise ValidationError('')
|
||||||
|
|
||||||
|
|
||||||
email_re = re.compile(
|
email_re = re.compile(
|
||||||
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
|
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'|^"([\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
|
r')@(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
|
||||||
|
validate_email = RegexValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')
|
||||||
def validate_email(value):
|
|
||||||
if not email_re.search(smart_unicode(value)):
|
|
||||||
raise ValidationError(_(u'Enter a valid e-mail address.'), code='invalid')
|
|
||||||
|
|
||||||
slug_re = re.compile(r'^[-\w]+$')
|
slug_re = re.compile(r'^[-\w]+$')
|
||||||
|
validate_slug = RegexValidator(slug_re, _(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
|
||||||
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'
|
|
||||||
)
|
|
||||||
|
|
||||||
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}$')
|
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}$')
|
||||||
|
validate_ipv4_address = RegexValidator(ipv4_re, _(u'Enter a valid IPv4 address.'), 'invalid')
|
||||||
def validate_ipv4_address(value):
|
|
||||||
if not ipv4_re.search(smart_unicode(value)):
|
|
||||||
raise ValidationError(
|
|
||||||
_(u'Enter a valid IPv4 address.'),
|
|
||||||
code="invalid"
|
|
||||||
)
|
|
||||||
|
|
||||||
comma_separated_int_list_re = re.compile('^[\d,]+$')
|
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):
|
class BaseValidator(object):
|
||||||
def __init__(self, max_value):
|
compare = lambda self, a, b: a is b
|
||||||
self.max_value = max_value
|
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):
|
def __call__(self, value):
|
||||||
if value > self.max_value:
|
cleaned = self.clean(value)
|
||||||
|
if self.compare(cleaned, self.limit_value):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_(u'Ensure this value is less than or equal to %s.') % self.max_value,
|
self.message,
|
||||||
code='max_value',
|
code=self.code,
|
||||||
params=(self.max_value,)
|
params={'limit_value': self.limit_value, 'show_value': cleaned}
|
||||||
)
|
)
|
||||||
|
|
||||||
class MinValueValidator(object):
|
class MaxValueValidator(BaseValidator):
|
||||||
def __init__(self, min_value):
|
compare = lambda self, a, b: a > b
|
||||||
self.min_value = min_value
|
message = _(u'Ensure this value is less than or equal to %(limit_value)s.')
|
||||||
|
code = 'max_value'
|
||||||
|
|
||||||
def __call__(self, value):
|
class MinValueValidator(BaseValidator):
|
||||||
if value < self.min_value:
|
compare = lambda self, a, b: a < b
|
||||||
raise ValidationError(
|
message = _(u'Ensure this value is greater than or equal to %(limit_value)s.')
|
||||||
_(u'Ensure this value is greater than or equal to %s.') % self.min_value,
|
code = 'min_value'
|
||||||
code='min_value',
|
|
||||||
params=(self.min_value,)
|
|
||||||
)
|
|
||||||
|
|
||||||
class MinLengthValidator(object):
|
class MinLengthValidator(BaseValidator):
|
||||||
def __init__(self, min_length):
|
compare = lambda self, a, b: a < b
|
||||||
self.min_length = min_length
|
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):
|
class MaxLengthValidator(BaseValidator):
|
||||||
value_len = len(value)
|
compare = lambda self, a, b: a > b
|
||||||
if value_len < self.min_length:
|
clean = lambda self, x: len(x)
|
||||||
raise ValidationError(
|
message = _(u'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).')
|
||||||
_(u'Ensure this value has at least %(min)d characters (it has %(length)d).'),
|
code = 'max_length'
|
||||||
code='min_length',
|
|
||||||
params={ 'min': self.min_length, 'length': value_len}
|
|
||||||
)
|
|
||||||
|
|
||||||
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):
|
class ComplexValidator(object):
|
||||||
def get_value(self, name, all_values, obj):
|
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 self.get_value(self.other_field, all_values, obj) in EMPTY_VALUES:
|
||||||
if value in EMPTY_VALUES:
|
if value in EMPTY_VALUES:
|
||||||
raise ValidationError('This field is required if %s is blank.' % self.other_field)
|
raise ValidationError('This field is required if %s is blank.' % self.other_field)
|
||||||
|
|
||||||
|
@ -204,8 +204,8 @@ class CharField(Field):
|
|||||||
class IntegerField(Field):
|
class IntegerField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _(u'Enter a whole number.'),
|
'invalid': _(u'Enter a whole number.'),
|
||||||
'max_value': _(u'Ensure this value is less 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 %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):
|
def __init__(self, max_value=None, min_value=None, *args, **kwargs):
|
||||||
@ -254,8 +254,8 @@ class FloatField(IntegerField):
|
|||||||
class DecimalField(Field):
|
class DecimalField(Field):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _(u'Enter a number.'),
|
'invalid': _(u'Enter a number.'),
|
||||||
'max_value': _(u'Ensure this value is less 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 %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_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_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.')
|
'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 = {'required': 'REQUIRED'}
|
||||||
>>> e['invalid'] = 'INVALID'
|
>>> e['invalid'] = 'INVALID'
|
||||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
>>> e['min_value'] = 'MIN VALUE IS %(limit_value)s'
|
||||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
>>> e['max_value'] = 'MAX VALUE IS %(limit_value)s'
|
||||||
>>> f = IntegerField(min_value=5, max_value=10, error_messages=e)
|
>>> f = IntegerField(min_value=5, max_value=10, error_messages=e)
|
||||||
>>> f.clean('')
|
>>> f.clean('')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
@ -50,8 +50,8 @@ ValidationError: [u'MAX VALUE IS 10']
|
|||||||
|
|
||||||
>>> e = {'required': 'REQUIRED'}
|
>>> e = {'required': 'REQUIRED'}
|
||||||
>>> e['invalid'] = 'INVALID'
|
>>> e['invalid'] = 'INVALID'
|
||||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
>>> e['min_value'] = 'MIN VALUE IS %(limit_value)s'
|
||||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
>>> e['max_value'] = 'MAX VALUE IS %(limit_value)s'
|
||||||
>>> f = FloatField(min_value=5, max_value=10, error_messages=e)
|
>>> f = FloatField(min_value=5, max_value=10, error_messages=e)
|
||||||
>>> f.clean('')
|
>>> f.clean('')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
@ -74,8 +74,8 @@ ValidationError: [u'MAX VALUE IS 10']
|
|||||||
|
|
||||||
>>> e = {'required': 'REQUIRED'}
|
>>> e = {'required': 'REQUIRED'}
|
||||||
>>> e['invalid'] = 'INVALID'
|
>>> e['invalid'] = 'INVALID'
|
||||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
>>> e['min_value'] = 'MIN VALUE IS %(limit_value)s'
|
||||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
>>> e['max_value'] = 'MAX VALUE IS %(limit_value)s'
|
||||||
>>> e['max_digits'] = 'MAX DIGITS IS %s'
|
>>> e['max_digits'] = 'MAX DIGITS IS %s'
|
||||||
>>> e['max_decimal_places'] = 'MAX DP IS %s'
|
>>> e['max_decimal_places'] = 'MAX DP IS %s'
|
||||||
>>> e['max_whole_digits'] = 'MAX DIGITS BEFORE DP IS %s'
|
>>> e['max_whole_digits'] = 'MAX DIGITS BEFORE DP IS %s'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user