Bug in handling out-of-date POST data with inlineformset_factory
|Reported by:||Ole Laursen||Owned by:||Anssi Kääriäinen|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
Hi, there's a bug in BaseModelFormSet._construct_form. There's a guard supposed to take care of bound forms, but if one of the entries has been deleted, self._existing_object(pk) will return None so you can end up in
if i < self.initial_form_count() and not kwargs.get('instance'): kwargs['instance'] = self.get_queryset()[i]
which is dangerous for a bound form where you must use ids to identify elements since element "i" can have changed from when the form was generated. In my case, I got an IndexError because there weren't enough elements left from a recent deletion.
I think the correct fix is to change the "if" to an "elif".
I've attached a patch with this fix and a test case for reproducing the problem (there doesn't seem to be any tests of model formsets?).
Note that the test as entered doesn't pass even with the fix because of issue #14877 - if you delete formset.save() and below in the test, it does pass.