summaryrefslogtreecommitdiff
path: root/docs/topics/forms/index.txt
blob: 86de7d1b06ab72f4ee4eb91f7b27586a2dd6ac19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
==================
Working with forms
==================

.. currentmodule:: django.forms

.. admonition:: About this document

    This document provides an introduction to the basics of web forms and how
    they are handled in Django. For a more detailed look at specific areas of
    the forms API, see :doc:`/ref/forms/api`, :doc:`/ref/forms/fields`, and
    :doc:`/ref/forms/validation`.

Unless you're planning to build websites and applications that do nothing but
publish content, and don't accept input from your visitors, you're going to
need to understand and use forms.

Django provides a range of tools and libraries to help you build forms to
accept input from site visitors, and then process and respond to the input.

HTML forms
==========

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 ``<input type="submit" value="Log in">`` element is triggered, the
data is returned to ``/admin/``.

``GET`` and ``POST``
--------------------

``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 :doc:`CSRF protection
</ref/csrf/>` 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.

Django's role in forms
======================

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.

Forms in Django
===============

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 :class:`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.

The Django :class:`Form` class
------------------------------

At the heart of this system of components is Django's :class:`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
:class:`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 :class:`ModelForm`
maps a model class's fields to HTML form ``<input>`` elements via a
:class:`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 :class:`DateField` and a
:class:`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
:doc:`Widget class </ref/forms/widgets/>`, but these can be overridden as
required.

Instantiating, processing, and rendering forms
----------------------------------------------

When rendering an object in Django, we generally:

1. get hold of it in the view (fetch it from the database, for example)
2. pass it to the template context
3. expand it to HTML markup using template variables

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.

Building a form
===============

The work that needs to be done
------------------------------

Suppose you want to create a simple form on your website, in order to obtain
the user's name. You'd need something like this in your template:

.. code-block:: html+django

    <form action="/your-name/" method="post">
        <label for="your_name">Your name: </label>
        <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
        <input type="submit" value="OK">
    </form>

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.

Building a form in Django
-------------------------

The :class:`Form` class
~~~~~~~~~~~~~~~~~~~~~~~

We already know what we want our HTML form to look like. Our starting point for
it in Django is this:

.. snippet::
    :filename: forms.py

    from django import forms

    class NameForm(forms.Form):
        your_name = forms.CharField(label='Your name', max_length=100)

This defines a :class:`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 :attr:`~Field.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
:attr:`~CharField.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 :class:`Form` instance has an :meth:`~Form.is_valid()` method, which runs
validation routines for all its fields. When this method is called, if all
fields contain valid data, it will:

* return ``True``
* place the form's data in its :attr:`~Form.cleaned_data` attribute.

The whole form, when rendered for the first time, will look like:

.. code-block:: html+django

    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" maxlength="100" required />

Note that it **does not** include the ``<form>`` tags, or a submit button.
We'll have to provide those ourselves in the template.

.. _using-a-form-in-a-view:

The view
~~~~~~~~

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:

.. snippet::
    :filename: views.py

    from django.shortcuts import render
    from django.http import HttpResponseRedirect

    from .forms import NameForm

    def get_name(request):
        # if this is a POST request we need to process the form data
        if request.method == 'POST':
            # create a form instance and populate it with data from the request:
            form = NameForm(request.POST)
            # check whether it's valid:
            if form.is_valid():
                # process the data in form.cleaned_data as required
                # ...
                # redirect to a new URL:
                return HttpResponseRedirect('/thanks/')

        # if a GET (or any other method) we'll create a blank form
        else:
            form = NameForm()

        return render(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.

.. _topics-forms-index-basic-form-template:

The template
~~~~~~~~~~~~

We don't need to do much in our ``name.html`` template. The simplest example
is:

.. code-block:: html+django

    <form action="/your-name/" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Submit" />
    </form>

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

.. admonition:: Forms and Cross Site Request Forgery protection

    Django ships with an easy-to-use :doc:`protection against Cross Site Request
    Forgeries </ref/csrf>`. When submitting a form via ``POST`` with
    CSRF protection enabled you must use the :ttag:`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.

.. admonition:: HTML5 input types and browser validation

    If your form includes a :class:`~django.forms.URLField`, an
    :class:`~django.forms.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 :class:`TextInput`.

We now have a working web form, described by a Django :class:`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.

More about Django :class:`Form` classes
=======================================

All form classes are created as subclasses of :class:`django.forms.Form`,
including the :doc:`ModelForm </topics/forms/modelforms>`, which you encounter
in Django's admin.

.. admonition:: Models and Forms

    In fact if your form is going to be used to directly add or edit a Django
    model, a :doc:`ModelForm </topics/forms/modelforms>` 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.

Bound and unbound form instances
--------------------------------

The distinction between :ref:`ref-forms-api-bound-unbound` is important:

* An unbound form has no data associated with it. When rendered to the user,
  it will be empty or will contain default values.

* A bound form has 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 what data to correct.

The form's :attr:`~Form.is_bound` attribute will tell you whether a form has
data bound to it or not.

More on fields
--------------

Consider a more useful form than our minimal example above, which we could use
to implement "contact me" functionality on a personal website:

.. snippet::
    :filename: forms.py

    from django import forms

    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100)
        message = forms.CharField(widget=forms.Textarea)
        sender = forms.EmailField()
        cc_myself = forms.BooleanField(required=False)

Our earlier form used a single field, ``your_name``, a :class:`CharField`. In
this case, our form has four fields: ``subject``, ``message``, ``sender`` and
``cc_myself``. :class:`CharField`, :class:`EmailField` and
:class:`BooleanField` are just three of the available field types; a full list
can be found in :doc:`/ref/forms/fields`.

Widgets
~~~~~~~

Each form field has a corresponding :doc:`Widget class </ref/forms/widgets/>`,
which in turn corresponds to an HTML form widget such as ``<input
type="text">``.

In most cases, the field will have a sensible default widget. For example, by
default, a :class:`CharField` will have a :class:`TextInput` widget, that
produces an ``<input type="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.

Field data
~~~~~~~~~~

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 :class:`IntegerField` and :class:`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:

.. snippet::
    :filename: views.py

    from django.core.mail import send_mail

    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)

        send_mail(subject, message, sender, recipients)
        return HttpResponseRedirect('/thanks/')

.. tip::

    For more on sending email from Django, see :doc:`/topics/email`.

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 :ref:`binding-uploaded-files`.

Working with form templates
===========================

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.

Form rendering options
----------------------

.. admonition:: Additional form template furniture

    Don't forget that a form's output does *not* include the surrounding
    ``<form>`` tags, or the form's ``submit`` control. You will have to provide
    these yourself.

There are other output options though for the ``<label>``/``<input>`` pairs:

* ``{{ form.as_table }}`` will render them as table cells wrapped in ``<tr>``
  tags

* ``{{ form.as_p }}`` will render them wrapped in ``<p>`` tags

* ``{{ form.as_ul }}`` will render them wrapped in ``<li>`` tags

Note that you'll have to provide the surrounding ``<table>`` or ``<ul>``
elements yourself.

Here's the output of ``{{ form.as_p }}`` for our ``ContactForm`` instance:

.. code-block:: html+django

    <p><label for="id_subject">Subject:</label>
        <input id="id_subject" type="text" name="subject" maxlength="100" required /></p>
    <p><label for="id_message">Message:</label>
        <textarea name="message" id="id_message" required></textarea></p>
    <p><label for="id_sender">Sender:</label>
        <input type="email" name="sender" id="id_sender" required /></p>
    <p><label for="id_cc_myself">Cc myself:</label>
        <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>

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 :ref:`customize the way in which labels and ids are generated
<ref-forms-api-configuring-label>`.

See :ref:`ref-forms-api-outputting-html` for more on this.

Rendering fields manually
-------------------------

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:

.. code-block:: html+django

    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="{{ form.subject.id_for_label }}">Email subject:</label>
        {{ form.subject }}
    </div>
    <div class="fieldWrapper">
        {{ form.message.errors }}
        <label for="{{ form.message.id_for_label }}">Your message:</label>
        {{ form.message }}
    </div>
    <div class="fieldWrapper">
        {{ form.sender.errors }}
        <label for="{{ form.sender.id_for_label }}">Your email address:</label>
        {{ form.sender }}
    </div>
    <div class="fieldWrapper">
        {{ form.cc_myself.errors }}
        <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
        {{ form.cc_myself }}
    </div>

Complete ``<label>`` elements can also be generated using the
:meth:`~django.forms.BoundField.label_tag`. For example:

.. code-block:: html+django

    <div class="fieldWrapper">
        {{ form.subject.errors }}
        {{ form.subject.label_tag }}
        {{ form.subject }}
    </div>


Rendering form error messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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:

.. code-block:: html+django

    <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:

.. code-block:: html+django

    {% if form.subject.errors %}
        <ol>
        {% for error in form.subject.errors %}
            <li><strong>{{ error|escape }}</strong></li>
        {% endfor %}
        </ol>
    {% endif %}

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:

.. code-block:: html+django

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

See :doc:`/ref/forms/api` for more on errors, styling, and working with form
attributes in templates.

Looping over the form's fields
------------------------------

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:

.. code-block:: html+django

    {% for field in form %}
        <div class="fieldWrapper">
            {{ field.errors }}
            {{ field.label_tag }} {{ field }}
            {% if field.help_text %}
            <p class="help">{{ field.help_text|safe }}</p>
            {% endif %}
        </div>
    {% endfor %}

Useful attributes on ``{{ field }}`` include:

``{{ 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. This
    includes the form's :attr:`~django.forms.Form.label_suffix`. For example,
    the default ``label_suffix`` is a colon::

        <label for="id_email">Email address:</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 ``<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:

.. code-block:: html+django

    {% if field.is_hidden %}
       {# Do something special #}
    {% endif %}

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

.. seealso::

    For a complete list of attributes and methods, see
    :class:`~django.forms.BoundField`.

Looping over hidden and visible fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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 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:

.. code-block:: html+django

    {# Include the hidden fields #}
    {% for hidden in form.hidden_fields %}
    {{ hidden }}
    {% endfor %}
    {# Include the visible fields #}
    {% for field in form.visible_fields %}
        <div class="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.

Reusable form templates
-----------------------

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 :ttag:`include` tag to reuse it in other templates:

.. code-block:: html+django

    # In your form template:
    {% include "form_snippet.html" %}

    # In form_snippet.html:
    {% for field in form %}
        <div class="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 :ttag:`include`
tag:

.. code-block:: html+django

    {% include "form_snippet.html" with form=comment_form %}

If you find yourself doing this often, you might consider creating a custom
:ref:`inclusion tag<howto-custom-template-tags-inclusion-tags>`.

Further topics
==============

This covers the basics, but forms can do a whole lot more:

.. toctree::
   :maxdepth: 2

   formsets
   modelforms
   media

.. seealso::

    :doc:`The Forms Reference </ref/forms/index>`
        Covers the full API reference, including form fields, form widgets,
        and form and field validation.