diff --git a/django/forms/fields.py b/django/forms/fields.py index 0ba7467191..96ecabfdc1 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -908,6 +908,7 @@ class MultiValueField(Field): out = self.compress(clean_data) self.validate(out) + self.run_validators(out) return out def compress(self, data_list): diff --git a/tests/regressiontests/forms/tests/forms.py b/tests/regressiontests/forms/tests/forms.py index 6425a007d1..3f529f23db 100644 --- a/tests/regressiontests/forms/tests/forms.py +++ b/tests/regressiontests/forms/tests/forms.py @@ -1778,3 +1778,32 @@ class FormsTestCase(TestCase): form = EventForm() self.assertHTMLEqual(form.as_ul(), u'') + + def test_multivalue_field_validation(self): + def bad_names(value): + if value == 'bad value': + raise ValidationError('bad value not allowed') + + class NameField(MultiValueField): + def __init__(self, fields=(), *args, **kwargs): + fields = (CharField(label='First name', max_length=10), + CharField(label='Last name', max_length=10)) + super(NameField, self).__init__(fields=fields, *args, **kwargs) + + def compress(self, data_list): + return ' '.join(data_list) + + class NameForm(Form): + name = NameField(validators=[bad_names]) + + form = NameForm(data={'name' : ['bad', 'value']}) + form.full_clean() + self.assertFalse(form.is_valid()) + self.assertEqual(form.errors, {'name': [u'bad value not allowed']}) + form = NameForm(data={'name' : ['should be overly', 'long for the field names']}) + self.assertFalse(form.is_valid()) + self.assertEqual(form.errors, {'name': [u'Ensure this value has at most 10 characters (it has 16).', + u'Ensure this value has at most 10 characters (it has 24).']}) + form = NameForm(data={'name' : ['fname', 'lname']}) + self.assertTrue(form.is_valid()) + self.assertEqual(form.cleaned_data, {'name' : 'fname lname'})