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)).

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top