1
0
mirror of https://github.com/django/django.git synced 2025-07-07 19:29:12 +00:00

[soc2009/model-validation] Make validators work with error messages containing paramters.

Implemented MaxValueValidator and MinValueValidator and migrated number
based form.Fields to use those instead of hardwired code. The validators
themselves are likely to change.

Covered by existing tests

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11186 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Honza Král 2009-07-05 13:27:20 +00:00
parent 63f244f144
commit d23f541f10
3 changed files with 39 additions and 17 deletions

View File

@ -35,7 +35,7 @@ class FieldError(Exception):
NON_FIELD_ERRORS = '__all__' NON_FIELD_ERRORS = '__all__'
class ValidationError(Exception): class ValidationError(Exception):
"""An error while validating data.""" """An error while validating data."""
def __init__(self, message, code=None): def __init__(self, message, code=None, params=None):
import operator import operator
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
""" """
@ -50,6 +50,7 @@ class ValidationError(Exception):
self.messages = [force_unicode(msg) for msg in message] self.messages = [force_unicode(msg) for msg in message]
else: else:
self.code = code self.code = code
self.params = params
message = force_unicode(message) message = force_unicode(message)
self.messages = [message] self.messages = [message]

View File

@ -22,6 +22,29 @@ def validate_email(value):
if not email_re.search(smart_unicode(value)): if not email_re.search(smart_unicode(value)):
raise ValidationError(_(u'Enter a valid e-mail address.'), code='invalid') raise ValidationError(_(u'Enter a valid e-mail address.'), code='invalid')
class MaxValueValidator(object):
def __init__(self, max_value):
self.max_value = max_value
def __call__(self, value):
if value > self.max_value:
raise ValidationError(
_(u'Ensure this value is less than or equal to %s.') % self.max_value,
code='max_value',
params=(self.max_value,)
)
class MinValueValidator(object):
def __init__(self, min_value):
self.min_value = min_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 ComplexValidator(object): class ComplexValidator(object):
def get_value(self, name, all_values, obj): def get_value(self, name, all_values, obj):
assert all_values or obj, "Either all_values or obj must be supplied" assert all_values or obj, "Either all_values or obj must be supplied"

View File

@ -128,7 +128,10 @@ class Field(object):
v(value) v(value)
except ValidationError, e: except ValidationError, e:
if hasattr(e, 'code'): if hasattr(e, 'code'):
errors.append(self.error_messages.get(e.code, e.messages[0])) message = self.error_messages.get(e.code, e.messages[0])
if e.params:
message = message % e.params
errors.append(message)
else: else:
errors.extend(e.messages) errors.extend(e.messages)
if errors: if errors:
@ -201,9 +204,13 @@ class IntegerField(Field):
} }
def __init__(self, max_value=None, min_value=None, *args, **kwargs): def __init__(self, max_value=None, min_value=None, *args, **kwargs):
self.max_value, self.min_value = max_value, min_value
super(IntegerField, self).__init__(*args, **kwargs) super(IntegerField, self).__init__(*args, **kwargs)
if max_value is not None:
self.validators.append(validators.MaxValueValidator(max_value))
if min_value is not None:
self.validators.append(validators.MinValueValidator(min_value))
def to_python(self, value): def to_python(self, value):
""" """
Validates that int() can be called on the input. Returns the result Validates that int() can be called on the input. Returns the result
@ -219,15 +226,6 @@ class IntegerField(Field):
raise ValidationError(self.error_messages['invalid']) raise ValidationError(self.error_messages['invalid'])
return value return value
def validate(self, value):
super(IntegerField, self).validate(value)
if value in validators.EMPTY_VALUES:
return
if self.max_value is not None and value > self.max_value:
raise ValidationError(self.error_messages['max_value'] % self.max_value)
if self.min_value is not None and value < self.min_value:
raise ValidationError(self.error_messages['min_value'] % self.min_value)
class FloatField(IntegerField): class FloatField(IntegerField):
default_error_messages = { default_error_messages = {
'invalid': _(u'Enter a number.'), 'invalid': _(u'Enter a number.'),
@ -261,10 +259,14 @@ class DecimalField(Field):
} }
def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs):
self.max_value, self.min_value = max_value, min_value
self.max_digits, self.decimal_places = max_digits, decimal_places self.max_digits, self.decimal_places = max_digits, decimal_places
Field.__init__(self, *args, **kwargs) Field.__init__(self, *args, **kwargs)
if max_value is not None:
self.validators.append(validators.MaxValueValidator(max_value))
if min_value is not None:
self.validators.append(validators.MinValueValidator(min_value))
def to_python(self, value): def to_python(self, value):
""" """
Validates that the input is a decimal number. Returns a Decimal Validates that the input is a decimal number. Returns a Decimal
@ -297,10 +299,6 @@ class DecimalField(Field):
digits = decimals digits = decimals
whole_digits = digits - decimals whole_digits = digits - decimals
if self.max_value is not None and value > self.max_value:
raise ValidationError(self.error_messages['max_value'] % self.max_value)
if self.min_value is not None and value < self.min_value:
raise ValidationError(self.error_messages['min_value'] % self.min_value)
if self.max_digits is not None and digits > self.max_digits: if self.max_digits is not None and digits > self.max_digits:
raise ValidationError(self.error_messages['max_digits'] % self.max_digits) raise ValidationError(self.error_messages['max_digits'] % self.max_digits)
if self.decimal_places is not None and decimals > self.decimal_places: if self.decimal_places is not None and decimals > self.decimal_places: