Refs #24121 -- Added __repr__() to BaseFormSet.

This commit is contained in:
Baptiste Mispelon 2021-12-11 20:17:29 +01:00 committed by Mariusz Felisiak
parent 61b332499d
commit e95e6425ac
2 changed files with 79 additions and 0 deletions

View File

@ -103,6 +103,22 @@ class BaseFormSet(RenderableFormMixin):
"""
return True
def __repr__(self):
if self._errors is None:
is_valid = 'Unknown'
else:
is_valid = (
self.is_bound and
not self._non_form_errors and
not any(form_errors for form_errors in self._errors)
)
return '<%s: bound=%s valid=%s total_forms=%s>' % (
self.__class__.__qualname__,
self.is_bound,
is_valid,
self.total_form_count(),
)
@cached_property
def management_form(self):
"""Return the ManagementForm instance for this FormSet."""

View File

@ -25,6 +25,12 @@ class Choice(Form):
ChoiceFormSet = formset_factory(Choice)
class ChoiceFormsetWithNonFormError(ChoiceFormSet):
def clean(self):
super().clean()
raise ValidationError('non-form error')
class FavoriteDrinkForm(Form):
name = CharField()
@ -1328,6 +1334,63 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertEqual(formset.non_form_errors().renderer, renderer)
self.assertEqual(formset.empty_form.renderer, renderer)
def test_repr(self):
valid_formset = self.make_choiceformset([('test', 1)])
valid_formset.full_clean()
invalid_formset = self.make_choiceformset([('test', '')])
invalid_formset.full_clean()
partially_invalid_formset = self.make_choiceformset(
[('test', '1'), ('test', '')],
)
partially_invalid_formset.full_clean()
invalid_formset_non_form_errors_only = self.make_choiceformset(
[('test', '')],
formset_class=ChoiceFormsetWithNonFormError,
)
invalid_formset_non_form_errors_only.full_clean()
cases = [
(
self.make_choiceformset(),
'<ChoiceFormSet: bound=False valid=Unknown total_forms=1>',
),
(
self.make_choiceformset(
formset_class=formset_factory(Choice, extra=10),
),
'<ChoiceFormSet: bound=False valid=Unknown total_forms=10>',
),
(
self.make_choiceformset([]),
'<ChoiceFormSet: bound=True valid=Unknown total_forms=0>',
),
(
self.make_choiceformset([('test', 1)]),
'<ChoiceFormSet: bound=True valid=Unknown total_forms=1>',
),
(valid_formset, '<ChoiceFormSet: bound=True valid=True total_forms=1>'),
(invalid_formset, '<ChoiceFormSet: bound=True valid=False total_forms=1>'),
(
partially_invalid_formset,
'<ChoiceFormSet: bound=True valid=False total_forms=2>',
),
(
invalid_formset_non_form_errors_only,
'<ChoiceFormsetWithNonFormError: bound=True valid=False total_forms=1>',
),
]
for formset, expected_repr in cases:
with self.subTest(expected_repr=expected_repr):
self.assertEqual(repr(formset), expected_repr)
def test_repr_do_not_trigger_validation(self):
formset = self.make_choiceformset([('test', 1)])
with mock.patch.object(formset, 'full_clean') as mocked_full_clean:
repr(formset)
mocked_full_clean.assert_not_called()
formset.is_valid()
mocked_full_clean.assert_called()
@jinja2_tests
class Jinja2FormsFormsetTestCase(FormsFormsetTestCase):