diff --git a/django/forms/forms.py b/django/forms/forms.py index e5df320673..d631b8f928 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -134,6 +134,18 @@ class BaseForm(object): def __str__(self): return self.as_table() + def __repr__(self): + if self._errors is None: + is_valid = "Unknown" + else: + is_valid = self.is_bound and not bool(self._errors) + return '<%(cls)s bound=%(bound)s, valid=%(valid)s, fields=(%(fields)s)>' % { + 'cls': self.__class__.__name__, + 'bound': self.is_bound, + 'valid': is_valid, + 'fields': ';'.join(self.fields), + } + def __iter__(self): for name in self.fields: yield self[name] diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index 0d8ae663a6..a0c858a5ed 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -2338,3 +2338,27 @@ class FormsTestCase(TestCase): """ ) + + def test_baseform_repr(self): + """ + Test for baseForm method __repr__ + """ + p = Person() + self.assertEqual(repr(p), "") + p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}) + self.assertEqual(repr(p), "") + p.is_valid() + self.assertEqual(repr(p), "") + p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': 'fakedate'}) + p.is_valid() + self.assertEqual(repr(p), "") + + def test_baseform_repr_dont_trigger_validation(self): + """ + Test to verify that __repr__ method don't trigger the validation + """ + p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': 'fakedate'}) + repr(p) + self.assertRaises(AttributeError, lambda: p.cleaned_data) + self.assertFalse(p.is_valid()) + self.assertEqual(p.cleaned_data, {'first_name': 'John', 'last_name': 'Lennon'})