﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
32911	django.forms.BaseFormSet.is_valid does not respect TOTAL_FORM_COUNT	Lorenzo Morandini	nobody	"#29113 (ticket) does not respect TOTAL_FORM_COUNT variable anymore when validating a formset.

Before:
{{{#!python
def is_valid(self):
    """"""Return True if every form in self.forms is valid.""""""
    if not self.is_bound:
        return False
    # We loop over every form.errors here rather than short circuiting on the
    # first failure to make sure validation gets triggered for every form.
    forms_valid = True
    # This triggers a full clean.
    self.errors
    for i in range(0, self.total_form_count()):
        form = self.forms[i]
        if self.can_delete and self._should_delete_form(form):
            # This form is going to be deleted so any of its errors
            # shouldn't cause the entire formset to be invalid.
            continue
        forms_valid &= form.is_valid()
    return forms_valid and not self.non_form_errors()
}}}

After:
{{{#!python
def is_valid(self):
    """"""Return True if every form in self.forms is valid.""""""
    if not self.is_bound:
        return False
    # Accessing errors triggers a full clean the first time only.
    self.errors
    # List comprehension ensures is_valid() is called for all forms.
    # Forms due to be deleted shouldn't cause the formset to be invalid.
    forms_valid = all([
        form.is_valid() for form in self.forms
        if not (self.can_delete and self._should_delete_form(form))
    ])
    return forms_valid and not self.non_form_errors()
}}}

The previous version used `total_form_count()` while the new version just iterates over `self.forms`.
This broke a view in my case where I had:
* a formset with some forms rendered in a page
* the last form of the formset was hidden and did NOT count in `TOTAL_FORM_COUNT`

Before the last form was ignored (and correctly not submitted), now it gets validated (even if it will not be submitted).
Depending on the `can_delete` param of the formset, this issue could lead to two outcomes:
* `can_delete=True`: `_should_delete_form()` throws `AttributeError: <form> has no attribute cleaned_data`
* `can_delete=False`: formset is invalid because of the last form

I consider it a bug since all the rest of the code of `BaseFormset` takes `TOTAL_FORM_COUNT` in consideration"	Bug	closed	Forms	3.2	Normal	invalid	form, formset	Jon Dufresne	Unreviewed	0	0	0	0	0	0
