Professional Documents
Culture Documents
While it is possible to process form submissions just using Django’s HttpRequest class,
using the form library takes care of a number of common form-related tasks. Using it, you
can:
Overview
Widget
A class that corresponds to an HTML form widget, e.g. <input type="text"> or
<textarea>. This handles rendering of the widget as HTML.
Field
A class that is responsible for doing validation, e.g. an EmailField that makes sure its
data is a valid email address.
Form
A collection of fields that knows how to validate itself and display itself as HTML.
Form Media
The CSS and JavaScript resources that are required to render a form.
The library is decoupled from the other Django components, such as the database layer,
views and templates. It relies only on Django settings, a couple of django.utils helper
functions and Django’s internationalization hooks (but you’re not required to be using
internationalization features to use this library).
Form objects
A Form object encapsulates a sequence of form fields and a collection of validation rules that
must be fulfilled in order for the form to be accepted. Form classes are created as
subclasses of django.forms.Form and make use of a declarative style that you’ll be familiar
with if you’ve used Django’s database models.
For example, consider a form used to implement “contact me” functionality on a personal
Web site:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
A form is composed of Field objects. In this case, our form has four fields: subject,
message, sender and cc_myself. CharField, EmailField and BooleanField are just three
of the available field types; a full list can be found in Form fields.
If your form is going to be used to directly add or edit a Django model, you can use a
ModelForm to avoid duplicating your model description.
The standard pattern for processing a form in a view looks like this:
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
})
1. If the form has not been submitted, an unbound instance of ContactForm is created and
passed to the template.
2. If the form has been submitted, a bound instance of the form is created using
request.POST. If the submitted data is valid, it is processed and the user is re-directed
to a "thanks" page.
3. If the form has been submitted but is invalid, the bound form instance is passed on to
the template.
The distinction between bound and unbound forms is important. An unbound form does
not have any data associated with it; when rendered to the user, it will be empty or will
contain default values. A bound form does have submitted data, and hence can be used to
tell if that data is valid. If an invalid bound form is rendered it can include inline error
messages telling the user where they went wrong.
See Bound and unbound forms for further information on the differences between bound and
unbound forms.
To see how to handle file uploads with your form see Binding uploaded files to a form for
more information.
Once is_valid() returns True, you can process the form submission safe in the knowledge
that it conforms to the validation rules defined by your form. While you could access
request.POST directly at this point, it is better to access form.cleaned_data. This data has
not only been validated but will also be converted in to the relevant Python types for you. In
the above example, cc_myself will be a boolean value. Likewise, fields such as
IntegerField and FloatField convert values to a Python int and float respectively. Note
that read-only fields are not available in form.cleaned_data (and setting a value in a
custom clean() method won't have any effect) because these fields are displayed as text
rather than as input elements, and thus are not posted back to the server.
Extending the above example, here's how the form data could be processed:
if form.is_valid():
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
sender = form.cleaned_data['sender']
cc_myself = form.cleaned_data['cc_myself']
recipients = ['info@example.com']
if cc_myself:
recipients.append(sender)
Forms are designed to work with the Django template language. In the above example, we
passed our ContactForm instance to the template using the context variable form. Here's a
simple example template:
The form only outputs its own fields; it is up to you to provide the surrounding <form> tags
and the submit button.
form.as_p will output the form with each form field and accompanying label wrapped in a
paragraph. Here's the output for our example template:
Note that each form field has an ID attribute set to id_<field-name>, which is referenced
by the accompanying label tag. This is important for ensuring forms are accessible to
assistive technology such as screen reader software. You can also customize the way in
which labels and ids are generated.
You can also use form.as_table to output table rows (you'll need to provide your own
<table> tags) and form.as_ul to output list items.
If the default generated HTML is not to your taste, you can completely customize the way a
form is presented using the Django template language. Extending the above example:
Each named form-field can be output to the template using {{ form.name_of_field }},
which will produce the HTML needed to display the form widget. Using
{{ form.name_of_field.errors }} displays a list of form errors, rendered as an unordered
list. This might look like:
<ul class="errorlist">
<li>Sender is required.</li>
</ul>
The list has a CSS class of errorlist to allow you to style its appearance. If you wish to
further customize the display of errors you can do so by looping over them:
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
If you're using the same HTML for each of your form fields, you can reduce duplicate code
by looping through each field in turn using a {% for %} loop:
Within this loop, {{ field }} is an instance of BoundField. BoundField also has the
following attributes, which can be useful in your templates:
{{ field.label }}
The label of the field, e.g. Email address.
{{ field.label_tag }}
The field's label wrapped in the appropriate HTML <label> tag, e.g.
<label for="id_email">Email address</label>
{{ field.html_name }}
The name of the field that will be used in the input element's name field. This takes the
form prefix into account, if it has been set.
{{ field.help_text }}
Any help text that has been associated with the field.
{{ field.errors }}
Outputs a <ul class="errorlist"> containing any validation errors corresponding to this
field. You can customize the presentation of the errors with a
{% for error in field.errors %} loop. In this case, each object in the loop is a simple
string containing the error message.
field.is_hidden
This attribute is True if the form field is a hidden field and False otherwise. It's not
particularly useful as a template variable, but could be useful in conditional tests such as:
{% if field.is_hidden %}
{# Do something special #}
{% endif %}
If you're manually laying out a form in a template, as opposed to relying on Django's default
form layout, you might want to treat <input type="hidden"> fields differently than
non-hidden fields. For example, because hidden fields don't display anything, putting error
messages "next to" the field could cause confusion for your users -- so errors for those fields
should be handled differently.
Django provides two methods on a form that allow you to loop over the hidden and visible
fields independently: hidden_fields() and visible_fields(). Here's a modification of an
earlier example that uses these two methods:
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Send message" /></p>
</form>
This example does not handle any errors in the hidden fields. Usually, an error in a hidden
field is a sign of form tampering, since normal form interaction won't alter them. However,
you could easily insert some error displays for those form errors, as well.
If your site uses the same rendering logic for forms in multiple places, you can reduce
duplication by saving the form's loop in a standalone template and using the include tag to
reuse it in other templates:
# In form_snippet.html:
If the form object passed to a template has a different name within the context, you can
alias it using the with argument of the include tag:
</form>
If you find yourself doing this often, you might consider creating a custom inclusion tag.
Further topics
This covers the basics, but forms can do a whole lot more:
Formsets
Form Media
See also
© 2005-2011 Django Software Foundation unless otherwise noted. Django is a registered trademark of the
Django Software Foundation. Hosting graciously provided by