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.