From 5cdb8f8c1ea7161ca9e3b702ec7cdd7e3cd0999a Mon Sep 17 00:00:00 2001 From: Anubhav Joshi Date: Thu, 24 Jul 2014 23:31:12 +0530 Subject: [PATCH] Fixed #16617 -- Added 'value' to BaseValidator params. Also allowed overriding the default messages in subclasses of BaseValidator. Thanks sperrygrove for initial patch. --- django/core/validators.py | 6 +++-- docs/ref/validators.txt | 24 +++++++++++++++---- .../forms_tests/tests/test_error_messages.py | 4 +++- tests/validators/tests.py | 8 ++++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/django/core/validators.py b/django/core/validators.py index 51bf94cca1..1d200c11d9 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -238,12 +238,14 @@ class BaseValidator(object): message = _('Ensure this value is %(limit_value)s (it is %(show_value)s).') code = 'limit_value' - def __init__(self, limit_value): + def __init__(self, limit_value, message=None): self.limit_value = limit_value + if message: + self.message = message def __call__(self, value): cleaned = self.clean(value) - params = {'limit_value': self.limit_value, 'show_value': cleaned} + params = {'limit_value': self.limit_value, 'show_value': cleaned, 'value': value} if self.compare(cleaned, self.limit_value): raise ValidationError(self.message, code=self.code, params=params) diff --git a/docs/ref/validators.txt b/docs/ref/validators.txt index 20368916ab..daa35862c0 100644 --- a/docs/ref/validators.txt +++ b/docs/ref/validators.txt @@ -171,28 +171,44 @@ to, or in lieu of custom ``field.clean()`` methods. ``MaxValueValidator`` --------------------- -.. class:: MaxValueValidator(max_value) +.. class:: MaxValueValidator(max_value, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of ``'max_value'`` if ``value`` is greater than ``max_value``. + .. versionchanged:: 1.8 + + The ``message`` parameter was added. + ``MinValueValidator`` --------------------- -.. class:: MinValueValidator(min_value) +.. class:: MinValueValidator(min_value, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of ``'min_value'`` if ``value`` is less than ``min_value``. + .. versionchanged:: 1.8 + + The ``message`` parameter was added. + ``MaxLengthValidator`` ---------------------- -.. class:: MaxLengthValidator(max_length) +.. class:: MaxLengthValidator(max_length, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of ``'max_length'`` if the length of ``value`` is greater than ``max_length``. + .. versionchanged:: 1.8 + + The ``message`` parameter was added. + ``MinLengthValidator`` ---------------------- -.. class:: MinLengthValidator(min_length) +.. class:: MinLengthValidator(min_length, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of ``'min_length'`` if the length of ``value`` is less than ``min_length``. + + .. versionchanged:: 1.8 + + The ``message`` parameter was added. diff --git a/tests/forms_tests/tests/test_error_messages.py b/tests/forms_tests/tests/test_error_messages.py index 94f5424c4e..75eddee254 100644 --- a/tests/forms_tests/tests/test_error_messages.py +++ b/tests/forms_tests/tests/test_error_messages.py @@ -154,10 +154,12 @@ class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin): e = { 'required': 'REQUIRED', 'invalid': 'INVALID', + 'max_length': '"%(value)s" has more than %(limit_value)d characters.', } - f = URLField(error_messages=e) + f = URLField(error_messages=e, max_length=17) self.assertFormErrors(['REQUIRED'], f.clean, '') self.assertFormErrors(['INVALID'], f.clean, 'abc.c') + self.assertFormErrors(['"http://djangoproject.com" has more than 17 characters.'], f.clean, 'djangoproject.com') def test_booleanfield(self): e = { diff --git a/tests/validators/tests.py b/tests/validators/tests.py index ccbe1c99b6..cb552619b4 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -14,6 +14,7 @@ from django.core.validators import ( validate_ipv46_address, validate_ipv4_address, validate_ipv6_address, validate_slug, ) +from django.test import SimpleTestCase from django.test.utils import str_prefix @@ -243,7 +244,7 @@ def create_simple_test_method(validator, expected, value, num): # Dynamically assemble a test class with the contents of TEST_DATA -class TestSimpleValidators(TestCase): +class TestSimpleValidators(SimpleTestCase): def test_single_message(self): v = ValidationError('Not Valid') self.assertEqual(str(v), str_prefix("[%(_)s'Not Valid']")) @@ -267,6 +268,11 @@ class TestSimpleValidators(TestCase): else: self.fail("TypeError not raised when flags and pre-compiled regex in RegexValidator") + def test_max_length_validator_message(self): + v = MaxLengthValidator(16, message='"%(value)s" has more than %(limit_value)d characters.') + with self.assertRaisesMessage(ValidationError, '"djangoproject.com" has more than 16 characters.'): + v('djangoproject.com') + test_counter = 0 for validator, value, expected in TEST_DATA: name, method = create_simple_test_method(validator, expected, value, test_counter)