When playing with Models and Forms…and formsets
Posted in Programming on March 23rd, 2010 by denivoriumThis is definitely an off the wall post, especially after such a long silence but more on that in another post. After beating my head against the wall trying to solve the following django exception I feel the need to post the solution in the vain hope that I will find my own words of wisdom when I run into this again. First the exception and solution, then backstory if necessary.
MultiValueDictKeyError at [pageUrl]
Key ‘[key]‘ not found in <QueryDict: {[request.POST]}>
The solution is actually right there in the exception if you read it right. The key is not in the POST. If the POST is returning a form constructed from an existing model, then there’s really only one way that could happen. Somewhere in the template system one or more model values got removed from the initial form. In my case this was a foreign key that I added to the model during development. Since I was displaying each form element individually in my template, my template didn’t have the new hidden value. Therefore it wasn’t getting included in the post even though it was in the initial form created in my view.
My somewhat generic solution in this case was to include the following snippet under the custom template layout.
{% for field in form.hidden_fields %}
{{ field.errors }}
{{ field }}
{% endfor %}
I include the field.errors mostly because I am still heavily in development and this helps me see at a glance that I broke something, or forgot to setup a new relationship correctly, etc.
On the face of it the exception looks pretty clear, Django can’t find the key in the POST. The part that confused me is that my form, modelformset actually, is loading correctly and is displaying the correct information. Furthermore the missing value was a reference to a foreign key that represents my model inheritance. So I incorrectly assumed that modelformset_factory had problems with inherited models. It turned out that I just need to make sure I update templates anytime I change model definitions!