diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 4d2d9fca47..6f4783116d 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -60,6 +60,10 @@ class BaseFormSet(StrAndUnicode): def __len__(self): return len(self.forms) + def __nonzero__(self): + """All formsets have a management form which is not included in the length""" + return True + def _management_form(self): """Returns the ManagementForm instance for this FormSet.""" if self.is_bound: diff --git a/tests/regressiontests/forms/tests/formsets.py b/tests/regressiontests/forms/tests/formsets.py index 4451fc76b1..869b6e35a6 100644 --- a/tests/regressiontests/forms/tests/formsets.py +++ b/tests/regressiontests/forms/tests/formsets.py @@ -805,6 +805,17 @@ class FormsFormsetTestCase(TestCase): self.assertEqual(str(reverse_formset[1]), str(forms[-2])) self.assertEqual(len(reverse_formset), len(forms)) + def test_formset_nonzero(self): + """ + Formsets with no forms should still evaluate as true. + Regression test for #15722 + """ + ChoiceFormset = formset_factory(Choice, extra=0) + formset = ChoiceFormset() + self.assertEqual(len(formset.forms), 0) + self.assertTrue(formset) + + data = { 'choices-TOTAL_FORMS': '1', # the number of forms rendered 'choices-INITIAL_FORMS': '0', # the number of forms with initial data