There are so many Web 1.0 holdovers built into it that seriously impede rapid Web 2.0 development.
Partially saving forms. Good luck with that. You cannot save parts of forms easily, you cannot perform validation on and save individual fields easily. It’s an all or nothing save. Or you have to roll everything yourself (again).
But that’s a whole other point. I don’t understand why web frameworks even care whether or not a whole form is “complete” and “valid” before saving them off to the database? Other parts of the application logic can determine whether all of the data they need is available, and react accordingly. In my case, I just added a is_user_valid() method, which checks to see that certain fields are in fact valid, before letting a user perform certain actions. (Robustness pretty much dictates that whatever processing code you have later on will need to be able to handle incorrect data anyway.)
Why does a web framework make it possible for a user to lose the majority of the things they’ve entered into a form, only because one single field was wrong?
Why isn’t it the other way around? Why doesn’t the framework save all of the form data that it can to the database model backend, and then prompt the user for a correction to the invalid field? Django’s Bound forms are just accidents waiting to happen in the User Experience. I know this, because during development, I’ve seen this, over and over again: You type something in, expect that it was saved (or worse, reload the page), and whoops, everything is gone. How stupid is that?
The design of Django’s form handling puts the majority of data at risk of being lost, due to the minority of data that is incorrect. This is just wrong-headed.
To solve the problem, I’ve been working on AJAX-based form-saving routines, but again, Django just gets in the way, and chokes whenever it sees a invalid input on a form you’re submitting.
Goddamn it Django, don’t worry about the whole form, just save what you can all the time and go for eventual consistency.
Update: The Django docs say this way at the bottom:
“Changed in Django 1.5: Django used to remove the cleaned_data attribute entirely if there were any errors in the form. Since version 1.5, cleaned_data is present even if the form doesn’t validate, but it contains only field values that did validate.”
But this is useless, if you’re using ModelForms. The stupid thing still raises a ValueError.
Update: Ok, it looks like one workaround for this is this one http://stackoverflow.com/a/4631007 which I’ll repeat here:
Before saving the form, just set all of the fields to required = False, so:
for name, field in form.fields.iteritems():
field.required = False
Update: Actually, this whole form-processing mess makes me think we’ve forgotten the adage by the late Jon Postel: “Be liberal in what you accept, and conservative in what you send.” Anything that keeps people from redundantly retyping things should be placed above the form processor’s need for perfect data before it will do anything at all with that data.