Read my book

I wrote books about Webpack and React. Check them out!

Wednesday, May 19, 2010

Django - ModelForm and FileField gotcha

I use Django's ModelForms a lot as they tend to save a lot of time. As can be guessed from the name, they provide means to generate forms based on models. Furthermore they provide validation and save functionality. Utterly cool, ain't it!

They are not without their issues, however. I bumped into one recently. It appears that the default widget by a FileField does not allow modification of the field if some data is provided to a ModelForm initially! Fortunately there's a workaround for this issue.



Initial Implementation


Here's my model:


my ModelForm:


and a couple of view functions:


As the templates won't make much difference I won't include them in this post. The official documentation covers that part well enough.

I used locals() just because I'm a lazy bastard. I suppose it's nicer to provide variables to a template via an explicit map...

The cool thing about ModelForms is that you can provide them an actual instance representing some data and it fills out the fields automagically. Except in this particular case!

Problem


It appears that the default widget used by a FileField does not allow modication. It renders the field as if it didn't have any data already. Fortunately there's a way around this limitation.

Solution


I noticed that the FileField works as expected in the admin interface. Why not to use it in this case as well?

Anyway to cut the story short, here we go, the solution:


Conclusion


It was just a matter of pointing the field to use the admin widget. If this would appear to be a more common idiom, it might make sense to implement a specific field encapsulating the hack to avoid modifications such as this on form level.