summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/forms/forms.py7
-rw-r--r--tests/regressiontests/forms/tests.py1
-rw-r--r--tests/regressiontests/forms/validators.py34
3 files changed, 39 insertions, 3 deletions
diff --git a/django/forms/forms.py b/django/forms/forms.py
index bb5b086d05..c7f07657d4 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -254,6 +254,7 @@ class BaseForm(StrAndUnicode):
for name, field in self.fields.items():
if not name in self.cleaned_data:
continue
+ failed = False
for v in field.validators:
# skip noncomplex validators, they have already been run on the Field
if not isinstance(v, ComplexValidator):
@@ -261,14 +262,14 @@ class BaseForm(StrAndUnicode):
try:
v(self.cleaned_data[name], all_values=self.cleaned_data)
except ValidationError, e:
+ failed = True
error_list = self._errors.setdefault(name, self.error_class())
if hasattr(e, 'code'):
error_list.append(field.error_messages.get(e.code, e.messages[0]))
else:
error_list.extend(e.messages)
- if name in self.cleaned_data:
- del self.cleaned_data[name]
-
+ if failed:
+ del self.cleaned_data[name]
try:
self.cleaned_data = self.clean()
except ValidationError, e:
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index c6881daff4..ef7326735d 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -32,6 +32,7 @@ from formsets import tests as formset_tests
from media import media_tests
from fields import TestFields
+from validators import TestFormWithValidators, TestFieldWithValidators
__test__ = {
'extra_tests': extra_tests,
diff --git a/tests/regressiontests/forms/validators.py b/tests/regressiontests/forms/validators.py
new file mode 100644
index 0000000000..becf4e2825
--- /dev/null
+++ b/tests/regressiontests/forms/validators.py
@@ -0,0 +1,34 @@
+from unittest import TestCase
+
+from django import forms
+from django.core import validators
+from django.core.exceptions import ValidationError
+
+class AlwaysFailingValidator(validators.ComplexValidator):
+ def __call__(self, value, all_values={}, obj=None):
+ raise ValidationError('AlwaysFailingValidator')
+
+class TestFieldWithValidators(TestCase):
+ def test_all_errors_get_reported(self):
+ field = forms.CharField(
+ validators=[validators.validate_integer, validators.validate_email,]
+ )
+ self.assertRaises(ValidationError, field.clean, 'not int nor mail')
+ try:
+ field.clean('not int nor mail')
+ except ValidationError, e:
+ self.assertEqual(2, len(e.messages))
+
+class TestFormWithValidators(TestCase):
+ def test_all_complex_validators_get_run_even_if_they_fail(self):
+ class MyForm(forms.Form):
+ validator_field = forms.CharField(
+ validators=[
+ AlwaysFailingValidator(),
+ AlwaysFailingValidator(),
+ ]
+ )
+ form = MyForm({'validator_field': 'some value'})
+ self.assertFalse(form.is_valid())
+ self.assertEqual(['validator_field'], form.errors.keys())
+ self.assertEqual(['AlwaysFailingValidator', 'AlwaysFailingValidator'], form.errors['validator_field'])