Fixed #18574 -- Make BaseFormSet.is_valid call its underlying forms' is_valid
Thanks Simon Charette for the report and the initial patch.
This commit is contained in:
parent
34dcf51e06
commit
66dfcc10b3
|
@ -267,7 +267,7 @@ class BaseFormSet(object):
|
||||||
|
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
"""
|
"""
|
||||||
Returns True if form.errors is empty for every form in self.forms.
|
Returns True if every form in self.forms is valid.
|
||||||
"""
|
"""
|
||||||
if not self.is_bound:
|
if not self.is_bound:
|
||||||
return False
|
return False
|
||||||
|
@ -282,8 +282,7 @@ class BaseFormSet(object):
|
||||||
# This form is going to be deleted so any of its errors
|
# This form is going to be deleted so any of its errors
|
||||||
# should not cause the entire formset to be invalid.
|
# should not cause the entire formset to be invalid.
|
||||||
continue
|
continue
|
||||||
if bool(self.errors[i]):
|
forms_valid &= form.is_valid()
|
||||||
forms_valid = False
|
|
||||||
return forms_valid and not bool(self.non_form_errors())
|
return forms_valid and not bool(self.non_form_errors())
|
||||||
|
|
||||||
def full_clean(self):
|
def full_clean(self):
|
||||||
|
|
|
@ -856,6 +856,27 @@ class FormsFormsetTestCase(TestCase):
|
||||||
formset = FavoriteDrinksFormSet(error_class=CustomErrorList)
|
formset = FavoriteDrinksFormSet(error_class=CustomErrorList)
|
||||||
self.assertEqual(formset.forms[0].error_class, CustomErrorList)
|
self.assertEqual(formset.forms[0].error_class, CustomErrorList)
|
||||||
|
|
||||||
|
def test_formset_calls_forms_is_valid(self):
|
||||||
|
# Regression tests for #18574 -- make sure formsets call
|
||||||
|
# is_valid() on each form.
|
||||||
|
|
||||||
|
class AnotherChoice(Choice):
|
||||||
|
def is_valid(self):
|
||||||
|
self.is_valid_called = True
|
||||||
|
return super(AnotherChoice, self).is_valid()
|
||||||
|
|
||||||
|
AnotherChoiceFormSet = formset_factory(AnotherChoice)
|
||||||
|
data = {
|
||||||
|
'choices-TOTAL_FORMS': '1', # number of forms rendered
|
||||||
|
'choices-INITIAL_FORMS': '0', # number of forms with initial data
|
||||||
|
'choices-MAX_NUM_FORMS': '0', # max number of forms
|
||||||
|
'choices-0-choice': 'Calexico',
|
||||||
|
'choices-0-votes': '100',
|
||||||
|
}
|
||||||
|
formset = AnotherChoiceFormSet(data, auto_id=False, prefix='choices')
|
||||||
|
self.assertTrue(formset.is_valid())
|
||||||
|
self.assertTrue(all([form.is_valid_called for form in formset.forms]))
|
||||||
|
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'choices-TOTAL_FORMS': '1', # the number of forms rendered
|
'choices-TOTAL_FORMS': '1', # the number of forms rendered
|
||||||
|
|
Loading…
Reference in New Issue