Opened 6 years ago
Last modified 6 years ago
#29739 closed Bug
BaseModelFormSet ignores excess rows in initial when extra < len(initial) — at Initial Version
Reported by: | Mark Gensler | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 2.1 |
Severity: | Normal | Keywords: | modelformset |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When passing initial data through BaseModelFormSet.__init__(..., initial=)
and the length of the initial data exceeds the number of extra forms defined in modelformsetfactory(..., extra=)
, then the data in the range self.initial_extra[self.extra:]
will be ignored.
E.g.
class Person(models.Model): name = models.CharField(max_length=100) initial = [{'name': 'Foo'}, {'name': 'Bar'}, {'name': 'Baz'}] PersonFormSet = modelformsetfactory(Person, extra=2) formset = MyModelFormSet(initial=initial)
Now, assuming that models.Person.objects.all()
is empty,
len(formset.forms) == 2 True
This is because BaseFormSet.total_form_count()
blindly uses self.extra and does not take into account the additional data in self.initial_extra
.
In order to work around this users would check len(initial)
before constructing the class and modify the extra
kwarg to be max(len(initial), some_default_value)
. This causes issues when writing abstract code which constructs the class separately from initialising it, or reuses the same class with differing initial data. In these cases the length of the initial data may not be known at the time of class construction.
Possible solutions are the number of extra forms equals self.extra + len(self.initial_extra)
or max(self.extra, len(self.initial_extra))
.