Fixed #26844 -- Made formset's validate_min validation ignore empty forms.

This commit is contained in:
Andrew Nester 2016-07-18 17:30:55 +03:00 committed by Tim Graham
parent 1e32e1cc95
commit f5c6295797
2 changed files with 16 additions and 1 deletions

View File

@ -336,11 +336,15 @@ class BaseFormSet(object):
""" """
self._errors = [] self._errors = []
self._non_form_errors = self.error_class() self._non_form_errors = self.error_class()
empty_forms_count = 0
if not self.is_bound: # Stop further processing. if not self.is_bound: # Stop further processing.
return return
for i in range(0, self.total_form_count()): for i in range(0, self.total_form_count()):
form = self.forms[i] form = self.forms[i]
if not form.has_changed():
empty_forms_count += 1
self._errors.append(form.errors) self._errors.append(form.errors)
try: try:
if (self.validate_max and if (self.validate_max and
@ -352,7 +356,7 @@ class BaseFormSet(object):
code='too_many_forms', code='too_many_forms',
) )
if (self.validate_min and if (self.validate_min and
self.total_form_count() - len(self.deleted_forms) < self.min_num): self.total_form_count() - len(self.deleted_forms) - empty_forms_count < self.min_num):
raise ValidationError(ungettext( raise ValidationError(ungettext(
"Please submit %d or more forms.", "Please submit %d or more forms.",
"Please submit %d or more forms.", self.min_num) % self.min_num, "Please submit %d or more forms.", self.min_num) % self.min_num,

View File

@ -377,6 +377,17 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertFalse(formset.is_valid()) self.assertFalse(formset.is_valid())
self.assertEqual(formset.non_form_errors(), ['Please submit 3 or more forms.']) self.assertEqual(formset.non_form_errors(), ['Please submit 3 or more forms.'])
def test_formset_validate_min_excludes_empty_forms(self):
data = {
'choices-TOTAL_FORMS': '2',
'choices-INITIAL_FORMS': '0',
}
ChoiceFormSet = formset_factory(Choice, extra=2, min_num=1, validate_min=True, can_delete=True)
formset = ChoiceFormSet(data, prefix='choices')
self.assertFalse(formset.has_changed())
self.assertFalse(formset.is_valid())
self.assertEqual(formset.non_form_errors(), ['Please submit 1 or more forms.'])
def test_second_form_partially_filled_2(self): def test_second_form_partially_filled_2(self):
# And once again, if we try to partially complete a form, validation will fail. # And once again, if we try to partially complete a form, validation will fail.