Fixed #26528 -- Allowed any iterable (e.g. tuple) as validators kwarg for form/model fields.
This commit is contained in:
parent
ec6121693f
commit
a885bca1df
|
@ -5,6 +5,7 @@ import collections
|
|||
import copy
|
||||
import datetime
|
||||
import decimal
|
||||
import itertools
|
||||
import uuid
|
||||
import warnings
|
||||
from base64 import b64decode, b64encode
|
||||
|
@ -531,9 +532,11 @@ class Field(RegisterLookupMixin):
|
|||
|
||||
@cached_property
|
||||
def validators(self):
|
||||
# Some validators can't be created at field initialization time.
|
||||
# This method provides a way to delay their creation until required.
|
||||
return self.default_validators + self._validators
|
||||
"""
|
||||
Some validators can't be created at field initialization time.
|
||||
This method provides a way to delay their creation until required.
|
||||
"""
|
||||
return list(itertools.chain(self.default_validators, self._validators))
|
||||
|
||||
def run_validators(self, value):
|
||||
if value in self.empty_values:
|
||||
|
|
|
@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
|||
|
||||
import copy
|
||||
import datetime
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
@ -119,7 +120,8 @@ class Field(object):
|
|||
messages.update(error_messages or {})
|
||||
self.error_messages = messages
|
||||
|
||||
self.validators = self.default_validators + validators
|
||||
self.validators = list(itertools.chain(self.default_validators, validators))
|
||||
|
||||
super(Field, self).__init__()
|
||||
|
||||
def prepare_value(self, value):
|
||||
|
|
|
@ -52,3 +52,17 @@ class TestFieldWithValidators(TestCase):
|
|||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(form.errors['string'], ["Letters only."])
|
||||
self.assertEqual(form.errors['string'], ["Letters only."])
|
||||
|
||||
def test_field_validators_can_be_any_iterable(self):
|
||||
class UserForm(forms.Form):
|
||||
full_name = forms.CharField(
|
||||
max_length=50,
|
||||
validators=(
|
||||
validators.validate_integer,
|
||||
validators.validate_email,
|
||||
)
|
||||
)
|
||||
|
||||
form = UserForm({'full_name': 'not int nor mail'})
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(form.errors['full_name'], ['Enter a valid integer.', 'Enter a valid email address.'])
|
||||
|
|
|
@ -31,6 +31,8 @@ class ModelToValidate(models.Model):
|
|||
)
|
||||
url = models.URLField(blank=True)
|
||||
f_with_custom_validator = models.IntegerField(blank=True, null=True, validators=[validate_answer_to_universe])
|
||||
f_with_iterable_of_validators = models.IntegerField(blank=True, null=True,
|
||||
validators=(validate_answer_to_universe,))
|
||||
slug = models.SlugField(blank=True)
|
||||
|
||||
def clean(self):
|
||||
|
|
|
@ -6,14 +6,26 @@ from .models import ModelToValidate
|
|||
|
||||
class TestModelsWithValidators(ValidationTestCase):
|
||||
def test_custom_validator_passes_for_correct_value(self):
|
||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42)
|
||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42,
|
||||
f_with_iterable_of_validators=42)
|
||||
self.assertIsNone(mtv.full_clean())
|
||||
|
||||
def test_custom_validator_raises_error_for_incorrect_value(self):
|
||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12)
|
||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12,
|
||||
f_with_iterable_of_validators=42)
|
||||
self.assertFailsValidation(mtv.full_clean, ['f_with_custom_validator'])
|
||||
self.assertFieldFailsValidationWithMessage(
|
||||
mtv.full_clean,
|
||||
'f_with_custom_validator',
|
||||
['This is not the answer to life, universe and everything!']
|
||||
)
|
||||
|
||||
def test_field_validators_can_be_any_iterable(self):
|
||||
mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42,
|
||||
f_with_iterable_of_validators=12)
|
||||
self.assertFailsValidation(mtv.full_clean, ['f_with_iterable_of_validators'])
|
||||
self.assertFieldFailsValidationWithMessage(
|
||||
mtv.full_clean,
|
||||
'f_with_iterable_of_validators',
|
||||
['This is not the answer to life, universe and everything!']
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue