`` tags) and ``form.as_ul`` to output list items.
Customizing the form template
-----------------------------
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::
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 %}
{% for error in form.subject.errors %}
{{ error|escape }}
{% endfor %}
{% endif %}
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::
Within this loop, ``{{ field }}`` is an instance of :class:`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 ```` tag,
e.g. ``Email address ``
``{{ 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 ```` 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 %}
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 `` ``
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::
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::
# In form_snippet.html:
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
{% 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::
If you find yourself doing this often, you might consider creating a custom
:ref:`inclusion tag`.
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 `
Covers the full API reference, including form fields, form widgets,
and form and field validation.