Fixed #28130 -- Fixed formset min_num validation with initial, unchanged forms.

Regression in f5c6295797.
This commit is contained in:
Tim Graham 2017-04-28 09:32:40 -04:00 committed by GitHub
parent eb4724a063
commit f04a404917
3 changed files with 30 additions and 1 deletions

View File

@ -322,7 +322,8 @@ class BaseFormSet:
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 are unchanged forms beyond those with initial data.
if not form.has_changed() and i >= self.initial_form_count():
empty_forms_count += 1 empty_forms_count += 1
self._errors.append(form.errors) self._errors.append(form.errors)

View File

@ -58,3 +58,6 @@ Bugfixes
* Fixed crash when overriding the template of * Fixed crash when overriding the template of
``django.views.static.directory_index()`` (:ticket:`28122`). ``django.views.static.directory_index()`` (:ticket:`28122`).
* Fixed a regression in formset ``min_num`` validation with unchanged forms
that have initial data (:ticket:`28130`).

View File

@ -402,6 +402,31 @@ 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_unchanged_forms(self):
"""
min_num validation doesn't consider unchanged forms with initial data
as "empty".
"""
initial = [
{'choice': 'Zero', 'votes': 0},
{'choice': 'One', 'votes': 0},
]
data = {
'choices-TOTAL_FORMS': '2',
'choices-INITIAL_FORMS': '2',
'choices-MIN_NUM_FORMS': '0',
'choices-MAX_NUM_FORMS': '2',
'choices-0-choice': 'Zero',
'choices-0-votes': '0',
'choices-1-choice': 'One',
'choices-1-votes': '1', # changed from initial
}
ChoiceFormSet = formset_factory(Choice, min_num=2, validate_min=True)
formset = ChoiceFormSet(data, auto_id=False, prefix='choices', initial=initial)
self.assertFalse(formset.forms[0].has_changed())
self.assertTrue(formset.forms[1].has_changed())
self.assertTrue(formset.is_valid())
def test_formset_validate_min_excludes_empty_forms(self): def test_formset_validate_min_excludes_empty_forms(self):
data = { data = {
'choices-TOTAL_FORMS': '2', 'choices-TOTAL_FORMS': '2',