I have a continual interest in finding the rough edges of learning Django. Some of the points of form and request handling have been coming up for me recently. What follows is an attempt at some explanation of the difference between request.POST
or request.GET
and form.cleaned_data
of a valid Django Form.
There are two different ways to get the info that you're looking for.
request.POST[somekey]
Where somekey is a string representing the associated html <input name="somekey" />
.
There is also forms.cleaned_data[somekey]
where somekey is the name of the attribute on the forms.Form
subclass that you've initialzed and checked the validation of earlier.
When you get it from request.POST it might not be valid, and it won't be convered into the proper python type. for example:
Consider the form:
from django import forms
class BirthDayForm(forms.Form):
birth_month = forms.IntegerField(min_value=1, max_value=12)
birth_day = forms.IntegerField(min_value=1, max_value=31)
birth_year = forms.IntegerField(min_value=1900, max_value=2014)
In your view you could implement this in this way:
from .forms import BirthDayForm
def birthday_view(request):
bday_form = BirthDayForm(request.POST or None)
if form.is_valid():
print bday.cleaned_data['birth_year']
return TemplateResponse(request, 'some_template.html', {"form": bday_form})
and in your template
<form method="POST">
{{ form.as_p }}
<input type="submit">
</form>
When you get the form it will print:
<form method="POST">
<input type="number" name="birth_month" id="id_birth_month" />
<input type="number" name="birth_day" id="id_birth_day" />
<input type="number" name="birth_year" id="id_birth_year" />
<input type="submit">
</form>
Now if you were to put a pdb into your view like this:
from .forms import BirthDayForm
def birthday_view(request):
bday_form = BirthDayForm(request.POST or None)
if form.is_valid():
import pdb; pdb.set_trace()
print bday.cleaned_data['birth_year']
return TemplateResponse(request, 'some_template.html', {"form": bday_form})
You would see (forgive me for not being exact, I haven't tested all this):
(pdb) type(request.POST['birth_year'])
> string
(pdb) type(form.cleaned_data['birth_year'])
> int
There are also several other complexities. You can add a "prefix" to a form, which would change the key of the request.POST dictionary, but it would NOT change the key of the cleaned_data.
consider:
from .forms import BirthDayForm
def birthday_view(request):
#add bday prefix to the form, because later we're going to have another form on this page with the same names, because it's a quiz page about your birthday, and the birthday of several dead presidents. sort of a "which dead president are you" quiz page for buzzfeed. It's not very fun.
bday_form = BirthDayForm(request.POST or None, prefix="bday")
if form.is_valid():
print bday.cleaned_data['birth_year']
return TemplateResponse(request, 'some_template.html', {"form": bday_form})
This would render as:
<form method="POST">
<input type="number" name="bday-birth_month" id="id_bday_birth_month" />
<input type="number" name="bday-birth_day" id="id_bday_birth_day" />
<input type="number" name="bday-birth_year" id="id_bday_birth_year" />
<input type="submit">
</form>
You can see that it changed the name and id attributes of the rendered form.
This would mean that if you put the PDB at the exact same spot...
(pdb) type(request.POST['birth_year'])
> KeyError, request.POST has no key birth_year
(pdb) request.POST.keys()
> ["bday-birth_month", "bday-birth_day", "bday-birth_year"]
But notice that the form.cleaned_data turns the keys back into the exact same name as the fields on the BirthDayForm that we defined earlier.
(pdb) type(form.cleaned_data['birth_year'])
> int
I think we could keep expanding this BirthDayForm concept to tease out the other things are conceptually a little difficult, like the validation process, converting crappy request.POST data into good python data, validating multiple fields together (my birthday is suddenly February 30th! because your form let me do that!)
31st March 2015
I won't ever give out your email address. I don't publish comments but if you'd like to write to me then you could use this form.
I'm Issac. I live in Oakland. I make things for fun and money. I use electronics and computers and software. I manage teams and projects top to bottom. I've worked as a consultant, software engineer, hardware designer, artist, technology director and team lead. I do occasional fabrication in wood and plastic and metal. I run a boutique interactive agency with my brother Kasey and a roving cast of experts at Kelly Creative Tech. I was the Director of Technology for Nonchalance during the The Latitude Society project. I was the Lead Web Developer and then Technical Marketing Engineer at Nebula, which made an OpenStack Appliance. I've been building things on the web and in person since leaving Ohio State University's Electrical and Computer engineering program in 2007. Lots of other really dorky things happened to me before that, like dropping out of high school to go to university, getting an Eagle Scout award, and getting 6th in a state-wide algebra competition. I have an affinity for hopscotch.