summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduard Stepanov <e.an.stepanov@gmail.com>2016-06-23 12:22:19 +0300
committerTim Graham <timograham@gmail.com>2016-06-28 11:39:20 -0400
commit49b4596cb4744e4b68d56e6a540a3e15c1582963 (patch)
treed3e924b25d768159a23784c2e2b1d004d561d03c
parentc9ae09addffb839403312131d4251e9d8b454508 (diff)
Fixed #26786 -- Avoided redundant max value validators on integer fields.
-rw-r--r--django/db/models/fields/__init__.py16
-rw-r--r--tests/model_fields/test_integerfield.py29
2 files changed, 41 insertions, 4 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 4fdba3de81..f4f3170a39 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -1812,14 +1812,22 @@ class IntegerField(Field):
def validators(self):
# These validators can't be added at field initialization time since
# they're based on values retrieved from `connection`.
- range_validators = []
+ validators_ = super(IntegerField, self).validators
internal_type = self.get_internal_type()
min_value, max_value = connection.ops.integer_field_range(internal_type)
if min_value is not None:
- range_validators.append(validators.MinValueValidator(min_value))
+ for validator in validators_:
+ if isinstance(validator, validators.MinValueValidator) and validator.limit_value >= min_value:
+ break
+ else:
+ validators_.append(validators.MinValueValidator(min_value))
if max_value is not None:
- range_validators.append(validators.MaxValueValidator(max_value))
- return super(IntegerField, self).validators + range_validators
+ for validator in validators_:
+ if isinstance(validator, validators.MaxValueValidator) and validator.limit_value <= max_value:
+ break
+ else:
+ validators_.append(validators.MaxValueValidator(max_value))
+ return validators_
def get_prep_value(self, value):
value = super(IntegerField, self).get_prep_value(value)
diff --git a/tests/model_fields/test_integerfield.py b/tests/model_fields/test_integerfield.py
index 27cbdb5259..a474e6e602 100644
--- a/tests/model_fields/test_integerfield.py
+++ b/tests/model_fields/test_integerfield.py
@@ -90,6 +90,35 @@ class IntegerFieldTests(TestCase):
instance.value = max_value
instance.full_clean()
+ def test_redundant_backend_range_validators(self):
+ """
+ If there are stricter validators than the ones from the database
+ backend then the backend validators aren't added.
+ """
+ min_backend_value, max_backend_value = self.backend_range
+
+ if min_backend_value is not None:
+ min_custom_value = min_backend_value + 1
+ ranged_value_field = self.model._meta.get_field('value').__class__(
+ validators=[validators.MinValueValidator(min_custom_value)]
+ )
+ field_range_message = validators.MinValueValidator.message % {
+ 'limit_value': min_custom_value,
+ }
+ with self.assertRaisesMessage(ValidationError, "[%r]" % field_range_message):
+ ranged_value_field.run_validators(min_backend_value - 1)
+
+ if max_backend_value is not None:
+ max_custom_value = max_backend_value - 1
+ ranged_value_field = self.model._meta.get_field('value').__class__(
+ validators=[validators.MaxValueValidator(max_custom_value)]
+ )
+ field_range_message = validators.MaxValueValidator.message % {
+ 'limit_value': max_custom_value,
+ }
+ with self.assertRaisesMessage(ValidationError, "[%r]" % field_range_message):
+ ranged_value_field.run_validators(max_backend_value + 1)
+
def test_types(self):
instance = self.model(value=0)
self.assertIsInstance(instance.value, six.integer_types)