In HTML, a form is a collection of elements inside <form>...</form> that
allow a visitor to do things like enter text, select options, manipulate
objects or controls, and so on, and then send that information back to the
server.

Some of these form interface elements - text input or checkboxes - are fairly
simple and are built into HTML itself. Others are much more complex; an
interface that pops up a date picker or allows you to move a slider or
manipulate controls will typically use JavaScript and CSS as well as HTML form
<input> elements to achieve these effects.

As well as its <input> elements, a form must specify two things:

where: the URL to which the data corresponding to the user’s input should
be returned

how: the HTTP method the data should be returned by

As an example, the login form for the Django admin contains several
<input> elements: one of type="text" for the username, one of
type="password" for the password, and one of type="submit" for the
“Log in” button. It also contains some hidden text fields that the user
doesn’t see, which Django uses to determine what to do next.

It also tells the browser that the form data should be sent to the URL
specified in the <form>’s action attribute - /admin/ - and that it
should be sent using the HTTP mechanism specified by the method attribute -
post.

When the <inputtype="submit"value="Login"> element is triggered, the
data is returned to /admin/.

GET and POST are the only HTTP methods to use when dealing with forms.

Django’s login form is returned using the POST method, in which the browser
bundles up the form data, encodes it for transmission, sends it to the server,
and then receives back its response.

GET, by contrast, bundles the submitted data into a string, and uses this
to compose a URL. The URL contains the address where the data must be sent, as
well as the data keys and values. You can see this in action if you do a search
in the Django documentation, which will produce a URL of the form
https://docs.djangoproject.com/search/?q=forms&release=1.

GET and POST are typically used for different purposes.

Any request that could be used to change the state of the system - for example,
a request that makes changes in the database - should use POST. GET
should be used only for requests that do not affect the state of the system.

GET would also be unsuitable for a password form, because the password
would appear in the URL, and thus, also in browser history and server logs,
all in plain text. Neither would it be suitable for large quantities of data,
or for binary data, such as an image. A Web application that uses GET
requests for admin forms is a security risk: it can be easy for an attacker to
mimic a form’s request to gain access to sensitive parts of the system.
POST, coupled with other protections like Django’s CSRF protection offers more control over access.

On the other hand, GET is suitable for things like a web search form,
because the URLs that represent a GET request can easily be bookmarked,
shared, or resubmitted.

Handling forms is a complex business. Consider Django’s admin, where numerous
items of data of several different types may need to be prepared for display in
a form, rendered as HTML, edited using a convenient interface, returned to the
server, validated and cleaned up, and then saved or passed on for further
processing.

Django’s form functionality can simplify and automate vast portions of this
work, and can also do it more securely than most programmers would be able to
do in code they wrote themselves.

Django handles three distinct parts of the work involved in forms:

preparing and restructuring data to make it ready for rendering

creating HTML forms for the data

receiving and processing submitted forms and data from the client

It is possible to write code that does all of this manually, but Django can
take care of it all for you.

We’ve described HTML forms briefly, but an HTML <form> is just one part of
the machinery required.

In the context of a Web application, ‘form’ might refer to that HTML
<form>, or to the Django Form that produces it, or to the
structured data returned when it is submitted, or to the end-to-end working
collection of these parts.

At the heart of this system of components is Django’s Form class. In
much the same way that a Django model describes the logical structure of an
object, its behavior, and the way its parts are represented to us, a
Form class describes a form and determines how it works and appears.

In a similar way that a model class’s fields map to database fields, a form
class’s fields map to HTML form <input> elements. (A ModelForm
maps a model class’s fields to HTML form <input> elements via a
Form; this is what the Django admin is based upon.)

A form’s fields are themselves classes; they manage form data and perform
validation when a form is submitted. A DateField and a
FileField handle very different kinds of data and have to do
different things with it.

A form field is represented to a user in the browser as an HTML “widget” - a
piece of user interface machinery. Each field type has an appropriate default
Widget class, but these can be overridden as
required.

Rendering a form in a template involves nearly the same work as rendering any
other kind of object, but there are some key differences.

In the case of a model instance that contained no data, it would rarely if ever
be useful to do anything with it in a template. On the other hand, it makes
perfect sense to render an unpopulated form - that’s what we do when we want
the user to populate it.

So when we handle a model instance in a view, we typically retrieve it from the
database. When we’re dealing with a form we typically instantiate it in the
view.

When we instantiate a form, we can opt to leave it empty or pre-populate it, for
example with:

data from a saved model instance (as in the case of admin forms for editing)

data that we have collated from other sources

data received from a previous HTML form submission

The last of these cases is the most interesting, because it’s what makes it
possible for users not just to read a website, but to send information back
to it too.

This tells the browser to return the form data to the URL /your-name/, using
the POST method. It will display a text field, labeled “Your name:”, and a
button marked “OK”. If the template context contains a current_name
variable, that will be used to pre-fill the your_name field.

You’ll need a view that renders the template containing the HTML form, and
that can supply the current_name field as appropriate.

When the form is submitted, the POST request which is sent to the server
will contain the form data.

Now you’ll also need a view corresponding to that /your-name/ URL which will
find the appropriate key/value pairs in the request, and then process them.

This is a very simple form. In practice, a form might contain dozens or
hundreds of fields, many of which might need to be pre-populated, and we might
expect the user to work through the edit-submit cycle several times before
concluding the operation.

We might require some validation to occur in the browser, even before the form
is submitted; we might want to use much more complex fields, that allow the
user to do things like pick dates from a calendar and so on.

At this point it’s much easier to get Django to do most of this work for us.

This defines a Form class with a single field (your_name). We’ve
applied a human-friendly label to the field, which will appear in the
<label> when it’s rendered (although in this case, the label
we specified is actually the same one that would be generated automatically if
we had omitted it).

The field’s maximum allowable length is defined by
max_length. This does two things. It puts a
maxlength="100" on the HTML <input> (so the browser should prevent the
user from entering more than that number of characters in the first place). It
also means that when Django receives the form back from the browser, it will
validate the length of the data.

A Form instance has an is_valid() method, which runs
validation routines for all its fields. When this method is called, if all
fields contain valid data, it will:

Form data sent back to a Django website is processed by a view, generally the
same view which published the form. This allows us to reuse some of the same
logic.

To handle the form we need to instantiate it in the view for the URL where we
want it to be published:

views.py

fromdjango.shortcutsimportrenderfromdjango.httpimportHttpResponseRedirectfrom.formsimportNameFormdefget_name(request):# if this is a POST request we need to process the form dataifrequest.method=='POST':# create a form instance and populate it with data from the request:form=NameForm(request.POST)# check whether it's valid:ifform.is_valid():# process the data in form.cleaned_data as required# ...# redirect to a new URL:returnHttpResponseRedirect('/thanks/')# if a GET (or any other method) we'll create a blank formelse:form=NameForm()returnrender(request,'name.html',{'form':form})

If we arrive at this view with a GET request, it will create an empty form
instance and place it in the template context to be rendered. This is what we
can expect to happen the first time we visit the URL.

If the form is submitted using a POST request, the view will once again
create a form instance and populate it with data from the request: form=NameForm(request.POST) This is called “binding data to the form” (it is now
a bound form).

We call the form’s is_valid() method; if it’s not True, we go back to
the template with the form. This time the form is no longer empty (unbound)
so the HTML form will be populated with the data previously submitted, where it
can be edited and corrected as required.

If is_valid() is True, we’ll now be able to find all the validated form
data in its cleaned_data attribute. We can use this data to update the
database or do other processing before sending an HTTP redirect to the browser
telling it where to go next.

All the form’s fields and their attributes will be unpacked into HTML markup
from that {{form}} by Django’s template language.

Forms and Cross Site Request Forgery protection

Django ships with an easy-to-use protection against Cross Site Request
Forgeries. When submitting a form via POST with
CSRF protection enabled you must use the csrf_token template tag
as in the preceding example. However, since CSRF protection is not
directly tied to forms in templates, this tag is omitted from the
following examples in this document.

HTML5 input types and browser validation

If your form includes a URLField, an
EmailField or any integer field type, Django will
use the url, email and number HTML5 input types. By default,
browsers may apply their own validation on these fields, which may be
stricter than Django’s validation. If you would like to disable this
behavior, set the novalidate attribute on the form tag, or specify
a different widget on the field, like TextInput.

We now have a working web form, described by a Django Form, processed
by a view, and rendered as an HTML <form>.

That’s all you need to get started, but the forms framework puts a lot more at
your fingertips. Once you understand the basics of the process described above,
you should be prepared to understand other features of the forms system and
ready to learn a bit more about the underlying machinery.

All form classes are created as subclasses of either django.forms.Form
or django.forms.ModelForm. You can think of ModelForm as a
subclass of Form. Form and ModelForm actually inherit common
functionality from a (private) BaseForm class, but this implementation
detail is rarely important.

Models and Forms

In fact if your form is going to be used to directly add or edit a Django
model, a ModelForm can save you a great
deal of time, effort, and code, because it will build a form, along with the
appropriate fields and their attributes, from a Model class.

Our earlier form used a single field, your_name, a CharField. 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.

Each form field has a corresponding Widget class,
which in turn corresponds to an HTML form widget such as <inputtype="text">.

In most cases, the field will have a sensible default widget. For example, by
default, a CharField will have a TextInput widget, that
produces an <inputtype="text"> in the HTML. If you needed <textarea>
instead, you’d specify the appropriate widget when defining your form field,
as we have done for the message field.

Whatever the data submitted with a form, once it has been successfully
validated by calling is_valid() (and is_valid() has returned True),
the validated form data will be in the form.cleaned_data dictionary. This
data will have been nicely converted into Python types for you.

Note

You can still access the unvalidated data directly from request.POST at
this point, but the validated data is better.

In the contact form example above, cc_myself will be a boolean value.
Likewise, fields such as IntegerField and FloatField convert
values to a Python int and float respectively.

Here’s how the form data could be processed in the view that handles this form:

Some field types need some extra handling. For example, files that are uploaded
using a form need to be handled differently (they can be retrieved from
request.FILES, rather than request.POST). For details of how to handle
file uploads with your form, see Binding uploaded files to a form.

All you need to do to get your form into a template is to place the form
instance into the template context. So if your form is called form in the
context, {{form}} will render its <label> and <input> elements
appropriately.

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 in ensuring that
forms are accessible to assistive technology such as screen reader software.
You can also customize the way in which labels and ids are generated.

We don’t have to let Django unpack the form’s fields; we can do it manually if
we like (allowing us to reorder the fields, for example). Each field is
available as an attribute of the form using {{form.name_of_field}}, and
in a Django template, will be rendered appropriately. For example:

Of course, the price of this flexibility is more work. Until now we haven’t had
to worry about how to display form errors, because that’s taken care of for us.
In this example we have had to make sure we take care of any errors for each
field and any errors for the form as a whole. Note {{form.non_field_errors}} at the top of the form and the template lookup for errors on each field.

Using {{form.name_of_field.errors}} displays a list of form errors,
rendered as an unordered list. This might look like:

<ulclass="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:

Non-field errors (and/or hidden field errors that are rendered at the top of
the form when using helpers like form.as_p()) will be rendered with an
additional class of nonfield to help distinguish them from field-specific
errors. For example, {{form.non_field_errors}} would look like:

<ulclass="errorlist nonfield"><li>Generic validation error</li></ul>

See The Forms API for more on errors, styling, and working with form
attributes in templates.

The field’s label wrapped in the appropriate HTML <label> tag. This
includes the form’s label_suffix. For example,
the default label_suffix is a colon:

<labelfor="id_email">Emailaddress:</label>

{{field.id_for_label}}

The ID that will be used for this field (id_email in the example
above). If you are constructing the label manually, you may want to use
this in lieu of label_tag. It’s also useful, for example, if you have
some inline JavaScript and want to avoid hardcoding the field’s ID.

{{field.value}}

The value of the field. e.g someone@example.com.

{{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 <ulclass="errorlist"> containing any validation errors
corresponding to this field. You can customize the presentation of
the errors with a {%forerrorinfield.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:

{%iffield.is_hidden%}{# Do something special #}{%endif%}

{{field.field}}

The Field instance from the form class that
this BoundField wraps. You can use it to access
Field attributes, e.g.
{{char_field.field.max_length}}.

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 <inputtype="hidden">
fields differently from 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:

{# Include the hidden fields #}{%forhiddeninform.hidden_fields%}{{hidden}}{%endfor%}{# Include the visible fields #}{%forfieldinform.visible_fields%}<divclass="fieldWrapper">{{field.errors}}{{field.label_tag}}{{field}}</div>{%endfor%}

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 your form template:
{%include"form_snippet.html"%}
# In form_snippet.html:
{%forfieldinform%}<divclass="fieldWrapper">{{field.errors}}{{field.label_tag}}{{field}}</div>{%endfor%}

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:

{%include"form_snippet.html"withform=comment_form%}

If you find yourself doing this often, you might consider creating a custom
inclusion tag.

This document is for Django's development version, which can be significantly different from previous releases. For older releases, use the version selector floating in the bottom right corner of this page.