diff --git a/django/core/validators.py b/django/core/validators.py index c1c9cd1c87e..38e4b6aa1d7 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -317,8 +317,9 @@ class BaseValidator: def __call__(self, value): cleaned = self.clean(value) - params = {'limit_value': self.limit_value, 'show_value': cleaned, 'value': value} - if self.compare(cleaned, self.limit_value): + limit_value = self.limit_value() if callable(self.limit_value) else self.limit_value + params = {'limit_value': limit_value, 'show_value': cleaned, 'value': value} + if self.compare(cleaned, limit_value): raise ValidationError(self.message, code=self.code, params=params) def __eq__(self, other): diff --git a/docs/ref/validators.txt b/docs/ref/validators.txt index 6294d519f81..b6a233014d5 100644 --- a/docs/ref/validators.txt +++ b/docs/ref/validators.txt @@ -236,7 +236,12 @@ to, or in lieu of custom ``field.clean()`` methods. .. class:: MaxValueValidator(limit_value, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of - ``'max_value'`` if ``value`` is greater than ``limit_value``. + ``'max_value'`` if ``value`` is greater than ``limit_value``, which may be + a callable. + + .. versionchanged:: 2.2 + + ``limit_value`` can now be a callable. ``MinValueValidator`` --------------------- @@ -244,7 +249,12 @@ to, or in lieu of custom ``field.clean()`` methods. .. class:: MinValueValidator(limit_value, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of - ``'min_value'`` if ``value`` is less than ``limit_value``. + ``'min_value'`` if ``value`` is less than ``limit_value``, which may be a + callable. + + .. versionchanged:: 2.2 + + ``limit_value`` can now be a callable. ``MaxLengthValidator`` ---------------------- @@ -252,7 +262,12 @@ to, or in lieu of custom ``field.clean()`` methods. .. class:: MaxLengthValidator(limit_value, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of - ``'max_length'`` if the length of ``value`` is greater than ``limit_value``. + ``'max_length'`` if the length of ``value`` is greater than + ``limit_value``, which may be a callable. + + .. versionchanged:: 2.2 + + ``limit_value`` can now be a callable. ``MinLengthValidator`` ---------------------- @@ -260,7 +275,12 @@ to, or in lieu of custom ``field.clean()`` methods. .. class:: MinLengthValidator(limit_value, message=None) Raises a :exc:`~django.core.exceptions.ValidationError` with a code of - ``'min_length'`` if the length of ``value`` is less than ``limit_value``. + ``'min_length'`` if the length of ``value`` is less than ``limit_value``, + which may be a callable. + + .. versionchanged:: 2.2 + + ``limit_value`` can now be a callable. ``DecimalValidator`` -------------------- diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt index 90099d9fc36..4a6e74fab31 100644 --- a/docs/releases/2.2.txt +++ b/docs/releases/2.2.txt @@ -259,7 +259,9 @@ URLs Validators ~~~~~~~~~~ -* ... +* :class:`.MaxValueValidator`, :class:`.MinValueValidator`, + :class:`.MinLengthValidator`, and :class:`.MaxLengthValidator` now accept + a callable ``limit_value``. .. _backwards-incompatible-2.2: diff --git a/tests/validators/tests.py b/tests/validators/tests.py index 9f69854902e..36d0b2a520b 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -203,6 +203,10 @@ TEST_DATA = [ (MinValueValidator(0), -1, ValidationError), (MinValueValidator(NOW), NOW - timedelta(days=1), ValidationError), + # limit_value may be a callable. + (MinValueValidator(lambda: 1), 0, ValidationError), + (MinValueValidator(lambda: 1), 1, None), + (MaxLengthValidator(10), '', None), (MaxLengthValidator(10), 10 * 'x', None),