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'})