Week 2¾: The Extra Form

Over the weekend I was hanging out with some other coders and one of them asked me if I could help with ModelForms. I said I hadn't written any ModelForms yet, but I was sure to have to learn about them soon, so I offered to take a look with them.

We had a view rendering our ModelForm in a ModelFormSet. We had it working okay, the content of our models appeared in form elements in the page, but there was one thing we didn't expect: Three forms for two objects, with the third one blank.

Did we have a third object in the database, one with an empty string as a value? Not according to the admin interface. Was there anything about this third form that looked different in the markup? No, it looked the same under the webkit Inspector. Where was it coming from?

Turns out that formset_factory (and thus modelformset_factory) has an extra parameter that does just that: creates extra forms in addition to those you provide data for. And it defaults to one.

Thanks for having the presence of mind to read the documentation, they said. I was so sure I must be doing something wrong!

I repeat that here for a few reasons: one as a reminder that reading the docs may save us some grief. (This is far from the only time the answer to a head-scratcher has been waiting in the docs all along, and I know it must drive the authors mad when we don't read them.) But also as a reminder that if your code is doing something unexpected, it's not always your fault. Django is written to be helpful, and sometimes that help comes in unanticipated ways, like rendering an extra form you didn't think you asked for.

Check your assumptions. Also check the assumptions which have been coded in to the tools you use.