Forms¶
request.POST binding to wrong parameter in forms¶
This is a common idiom in a view.:
def view_func(request):
form = FormClass()
if request.method == 'POST':
form=FormClass(request.POST)#Gotcha
....
payload = {'form':form}
return render_to_response(...)
Now suppose we edited our form class to:
class FormClass(forms.Form):
def __init__(self, user = None, *args, **kwargs):
...
request.POST will bind to user, when we meant to be the POST data.
Solution:
Rewrite the gotcha line as
form=FormClass(data=request.POST)
Using form.cleaned_data before calling form.is_valid¶
Even if you are sure your form passes validation, you still need to call is_valid. form.cleaned_data is calculated after form.is_valid is called, which you probably are using in your form.save().
Overriding form.save in ModelForms:¶
Similar to models.save, forms.save are often (wrongly) overriden as forms.save:
def forms.save(self):
...
super(FormCLass, self).save()
This won’t work in many cases, for example form.save(commit=False)
Solution:
Always save as:
def forms.save(self, *args, **kwargs):
...
super(FormClass, self).save(*args, **kwargs)
Not calling superclass __init__¶
You might want to change the widget of a particular form field and this can be done by overriding Form’s __init__.:
from django.contrib.admin.widgets import AdminFileWidget
class FormClass(forms.ModelForm):
class Meta:
model = Profile
def __init__(self, *args, **kwargs):
self.fields['picture'].widget = AdminFilewidget() #Gotcha
self.fields is populated after __init__ of ModelForm has executed. So, make sure to call superclass __init__ before accessing self.fields.:
def __init__(self, *args, **kwargs):
super(FormClass, self).__init__(*args, **kwargs)
self.fields['picture'].widget = AdminFilewidget()