diff --git a/django/core/exceptions.py b/django/core/exceptions.py index e1e6da268a..9f9aeb29a5 100644 --- a/django/core/exceptions.py +++ b/django/core/exceptions.py @@ -35,7 +35,7 @@ class FieldError(Exception): NON_FIELD_ERRORS = '__all__' class ValidationError(Exception): """An error while validating data.""" - def __init__(self, message, code=None): + def __init__(self, message, code=None, params=None): import operator from django.utils.encoding import force_unicode """ @@ -50,6 +50,7 @@ class ValidationError(Exception): self.messages = [force_unicode(msg) for msg in message] else: self.code = code + self.params = params message = force_unicode(message) self.messages = [message] diff --git a/django/core/validators.py b/django/core/validators.py index aeba5cd835..1426c1c903 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -22,6 +22,29 @@ def validate_email(value): if not email_re.search(smart_unicode(value)): 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): def get_value(self, name, all_values, obj): assert all_values or obj, "Either all_values or obj must be supplied" diff --git a/django/forms/fields.py b/django/forms/fields.py index cff1970450..8fa66cf0d6 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -128,7 +128,10 @@ class Field(object): v(value) except ValidationError, e: 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: errors.extend(e.messages) if errors: @@ -201,9 +204,13 @@ class IntegerField(Field): } 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) + 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): """ 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']) 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): default_error_messages = { '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): - self.max_value, self.min_value = max_value, min_value self.max_digits, self.decimal_places = max_digits, decimal_places 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): """ Validates that the input is a decimal number. Returns a Decimal @@ -297,10 +299,6 @@ class DecimalField(Field): 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: raise ValidationError(self.error_messages['max_digits'] % self.max_digits) if self.decimal_places is not None and decimals > self.decimal_places: