PageRenderTime 29ms CodeModel.GetById 23ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/docs/topics/forms/index.txt

https://code.google.com/p/mango-py/
Plain Text | 407 lines | 316 code | 91 blank | 0 comment | 0 complexity | 36fe65695638d0647b1400e637d5e5a7 MD5 | raw file
  1==================
  2Working with forms
  3==================
  4
  5.. admonition:: About this document
  6
  7    This document provides an introduction to Django's form handling features.
  8    For a more detailed look at specific areas of the forms API, see
  9    :doc:`/ref/forms/api`, :doc:`/ref/forms/fields`, and
 10    :doc:`/ref/forms/validation`.
 11
 12.. highlightlang:: html+django
 13
 14``django.forms`` is Django's form-handling library.
 15
 16While it is possible to process form submissions just using Django's
 17:class:`~django.http.HttpRequest` class, using the form library takes care of a
 18number of common form-related tasks. Using it, you can:
 19
 20    1. Display an HTML form with automatically generated form widgets.
 21    2. Check submitted data against a set of validation rules.
 22    3. Redisplay a form in the case of validation errors.
 23    4. Convert submitted form data to the relevant Python data types.
 24
 25Overview
 26========
 27
 28The library deals with these concepts:
 29
 30.. glossary::
 31
 32    Widget
 33        A class that corresponds to an HTML form widget, e.g.
 34        ``<input type="text">`` or ``<textarea>``. This handles rendering of the
 35        widget as HTML.
 36
 37    Field
 38        A class that is responsible for doing validation, e.g.
 39        an ``EmailField`` that makes sure its data is a valid e-mail address.
 40
 41    Form
 42        A collection of fields that knows how to validate itself and
 43        display itself as HTML.
 44
 45    Form Media
 46        The CSS and JavaScript resources that are required to render a form.
 47
 48The library is decoupled from the other Django components, such as the database
 49layer, views and templates. It relies only on Django settings, a couple of
 50``django.utils`` helper functions and Django's internationalization hooks (but
 51you're not required to be using internationalization features to use this
 52library).
 53
 54Form objects
 55============
 56
 57A Form object encapsulates a sequence of form fields and a collection of
 58validation rules that must be fulfilled in order for the form to be accepted.
 59Form classes are created as subclasses of ``django.forms.Form`` and
 60make use of a declarative style that you'll be familiar with if you've used
 61Django's database models.
 62
 63For example, consider a form used to implement "contact me" functionality on a
 64personal Web site:
 65
 66.. code-block:: python
 67
 68    from django import forms
 69
 70    class ContactForm(forms.Form):
 71        subject = forms.CharField(max_length=100)
 72        message = forms.CharField()
 73        sender = forms.EmailField()
 74        cc_myself = forms.BooleanField(required=False)
 75
 76A form is composed of ``Field`` objects. In this case, our form has four
 77fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. ``CharField``,
 78``EmailField`` and ``BooleanField`` are just three of the available field types;
 79a full list can be found in :doc:`/ref/forms/fields`.
 80
 81If your form is going to be used to directly add or edit a Django model, you can
 82use a :doc:`ModelForm </topics/forms/modelforms>` to avoid duplicating your model
 83description.
 84
 85Using a form in a view
 86----------------------
 87
 88The standard pattern for processing a form in a view looks like this:
 89
 90.. code-block:: python
 91
 92   def contact(request):
 93       if request.method == 'POST': # If the form has been submitted...
 94           form = ContactForm(request.POST) # A form bound to the POST data
 95           if form.is_valid(): # All validation rules pass
 96               # Process the data in form.cleaned_data
 97               # ...
 98               return HttpResponseRedirect('/thanks/') # Redirect after POST
 99       else:
100           form = ContactForm() # An unbound form
101
102       return render_to_response('contact.html', {
103           'form': form,
104       })
105
106
107There are three code paths here:
108
109    1. If the form has not been submitted, an unbound instance of ContactForm is
110       created and passed to the template.
111    2. If the form has been submitted, a bound instance of the form is created
112       using ``request.POST``. If the submitted data is valid, it is processed
113       and the user is re-directed to a "thanks" page.
114    3. If the form has been submitted but is invalid, the bound form instance is
115       passed on to the template.
116
117The distinction between **bound** and **unbound** forms is important. An unbound
118form does not have any data associated with it; when rendered to the user, it
119will be empty or will contain default values. A bound form does have submitted
120data, and hence can be used to tell if that data is valid. If an invalid bound
121form is rendered it can include inline error messages telling the user where
122they went wrong.
123
124See :ref:`ref-forms-api-bound-unbound` for further information on the
125differences between bound and unbound forms.
126
127Handling file uploads with a form
128---------------------------------
129
130To see how to handle file uploads with your form see
131:ref:`binding-uploaded-files` for more information.
132
133Processing the data from a form
134-------------------------------
135
136Once ``is_valid()`` returns ``True``, you can process the form submission safe
137in the knowledge that it conforms to the validation rules defined by your form.
138While you could access ``request.POST`` directly at this point, it is better to
139access ``form.cleaned_data``. This data has not only been validated but will
140also be converted in to the relevant Python types for you. In the above example,
141``cc_myself`` will be a boolean value. Likewise, fields such as ``IntegerField``
142and ``FloatField`` convert values to a Python int and float respectively. Note
143that read-only fields are not available in ``form.cleaned_data`` (and setting
144a value in a custom ``clean()`` method won't have any effect) because these
145fields are displayed as text rather than as input elements, and thus are not
146posted back to the server.
147
148Extending the above example, here's how the form data could be processed:
149
150.. code-block:: python
151
152    if form.is_valid():
153        subject = form.cleaned_data['subject']
154        message = form.cleaned_data['message']
155        sender = form.cleaned_data['sender']
156        cc_myself = form.cleaned_data['cc_myself']
157
158        recipients = ['info@example.com']
159        if cc_myself:
160            recipients.append(sender)
161
162        from django.core.mail import send_mail
163        send_mail(subject, message, sender, recipients)
164        return HttpResponseRedirect('/thanks/') # Redirect after POST
165
166For more on sending e-mail from Django, see :doc:`/topics/email`.
167
168Displaying a form using a template
169----------------------------------
170
171Forms are designed to work with the Django template language. In the above
172example, we passed our ``ContactForm`` instance to the template using the
173context variable ``form``. Here's a simple example template::
174
175    <form action="/contact/" method="post">{% csrf_token %}
176    {{ form.as_p }}
177    <input type="submit" value="Submit" />
178    </form>
179
180The form only outputs its own fields; it is up to you to provide the surrounding
181``<form>`` tags and the submit button.
182
183.. admonition:: Forms and Cross Site Request Forgery protection
184
185   Django ships with an easy-to-use :doc:`protection against Cross Site Request
186   Forgeries </ref/contrib/csrf>`. When submitting a form via POST with
187   CSRF protection enabled you must use the :ttag:`csrf_token` template tag
188   as in the preceding example. However, since CSRF protection is not
189   directly tied to forms in templates, this tag is omitted from the
190   following examples in this document.
191
192``form.as_p`` will output the form with each form field and accompanying label
193wrapped in a paragraph. Here's the output for our example template::
194
195   <form action="/contact/" method="post">
196   <p><label for="id_subject">Subject:</label>
197       <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
198   <p><label for="id_message">Message:</label>
199       <input type="text" name="message" id="id_message" /></p>
200   <p><label for="id_sender">Sender:</label>
201       <input type="text" name="sender" id="id_sender" /></p>
202   <p><label for="id_cc_myself">Cc myself:</label>
203       <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
204   <input type="submit" value="Submit" />
205   </form>
206
207Note that each form field has an ID attribute set to ``id_<field-name>``, which
208is referenced by the accompanying label tag. This is important for ensuring
209forms are accessible to assistive technology such as screen reader software. You
210can also :ref:`customize the way in which labels and ids are generated
211<ref-forms-api-configuring-label>`.
212
213You can also use ``form.as_table`` to output table rows (you'll need to provide
214your own ``<table>`` tags) and ``form.as_ul`` to output list items.
215
216Customizing the form template
217-----------------------------
218
219If the default generated HTML is not to your taste, you can completely customize
220the way a form is presented using the Django template language. Extending the
221above example::
222
223    <form action="/contact/" method="post">
224        {{ form.non_field_errors }}
225        <div class="fieldWrapper">
226            {{ form.subject.errors }}
227            <label for="id_subject">E-mail subject:</label>
228            {{ form.subject }}
229        </div>
230        <div class="fieldWrapper">
231            {{ form.message.errors }}
232            <label for="id_message">Your message:</label>
233            {{ form.message }}
234        </div>
235        <div class="fieldWrapper">
236            {{ form.sender.errors }}
237            <label for="id_sender">Your email address:</label>
238            {{ form.sender }}
239        </div>
240        <div class="fieldWrapper">
241            {{ form.cc_myself.errors }}
242            <label for="id_cc_myself">CC yourself?</label>
243            {{ form.cc_myself }}
244        </div>
245        <p><input type="submit" value="Send message" /></p>
246    </form>
247
248Each named form-field can be output to the template using
249``{{ form.name_of_field }}``, which will produce the HTML needed to display the
250form widget. Using ``{{ form.name_of_field.errors }}`` displays a list of form
251errors, rendered as an unordered list. This might look like::
252
253   <ul class="errorlist">
254       <li>Sender is required.</li>
255   </ul>
256
257The list has a CSS class of ``errorlist`` to allow you to style its appearance.
258If you wish to further customize the display of errors you can do so by looping
259over them::
260
261    {% if form.subject.errors %}
262        <ol>
263        {% for error in form.subject.errors %}
264            <li><strong>{{ error|escape }}</strong></li>
265        {% endfor %}
266        </ol>
267    {% endif %}
268
269Looping over the form's fields
270------------------------------
271
272If you're using the same HTML for each of your form fields, you can reduce
273duplicate code by looping through each field in turn using a ``{% for %}``
274loop::
275
276    <form action="/contact/" method="post">
277        {% for field in form %}
278            <div class="fieldWrapper">
279                {{ field.errors }}
280                {{ field.label_tag }}: {{ field }}
281            </div>
282        {% endfor %}
283        <p><input type="submit" value="Send message" /></p>
284    </form>
285
286Within this loop, ``{{ field }}`` is an instance of :class:`BoundField`.
287``BoundField`` also has the following attributes, which can be useful in your
288templates:
289
290    ``{{ field.label }}``
291        The label of the field, e.g. ``E-mail address``.
292
293    ``{{ field.label_tag }}``
294        The field's label wrapped in the appropriate HTML ``<label>`` tag,
295        e.g. ``<label for="id_email">E-mail address</label>``
296
297    ``{{ field.html_name }}``
298        The name of the field that will be used in the input element's name
299        field. This takes the form prefix into account, if it has been set.
300
301    ``{{ field.help_text }}``
302        Any help text that has been associated with the field.
303
304    ``{{ field.errors }}``
305        Outputs a ``<ul class="errorlist">`` containing any validation errors
306        corresponding to this field. You can customize the presentation of
307        the errors with a ``{% for error in field.errors %}`` loop. In this
308        case, each object in the loop is a simple string containing the error
309        message.
310
311    ``field.is_hidden``
312        This attribute is ``True`` if the form field is a hidden field and
313        ``False`` otherwise. It's not particularly useful as a template
314        variable, but could be useful in conditional tests such as::
315
316            {% if field.is_hidden %}
317               {# Do something special #}
318            {% endif %}
319
320Looping over hidden and visible fields
321~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
322
323If you're manually laying out a form in a template, as opposed to relying on
324Django's default form layout, you might want to treat ``<input type="hidden">``
325fields differently than non-hidden fields. For example, because hidden fields
326don't display anything, putting error messages "next to" the field could cause
327confusion for your users -- so errors for those fields should be handled
328differently.
329
330Django provides two methods on a form that allow you to loop over the hidden
331and visible fields independently: ``hidden_fields()`` and
332``visible_fields()``. Here's a modification of an earlier example that uses
333these two methods::
334
335    <form action="/contact/" method="post">
336        {% for field in form.visible_fields %}
337            <div class="fieldWrapper">
338
339                {# Include the hidden fields in the form #}
340                {% if forloop.first %}
341                    {% for hidden in form.hidden_fields %}
342                    {{ hidden }}
343                    {% endfor %}
344                {% endif %}
345
346                {{ field.errors }}
347                {{ field.label_tag }}: {{ field }}
348            </div>
349        {% endfor %}
350        <p><input type="submit" value="Send message" /></p>
351    </form>
352
353This example does not handle any errors in the hidden fields. Usually, an
354error in a hidden field is a sign of form tampering, since normal form
355interaction won't alter them. However, you could easily insert some error
356displays for those form errors, as well.
357
358Reusable form templates
359-----------------------
360
361If your site uses the same rendering logic for forms in multiple places, you
362can reduce duplication by saving the form's loop in a standalone template and
363using the :ttag:`include` tag to reuse it in other templates::
364
365    <form action="/contact/" method="post">
366        {% include "form_snippet.html" %}
367        <p><input type="submit" value="Send message" /></p>
368    </form>
369
370    # In form_snippet.html:
371
372    {% for field in form %}
373        <div class="fieldWrapper">
374            {{ field.errors }}
375            {{ field.label_tag }}: {{ field }}
376        </div>
377    {% endfor %}
378
379If the form object passed to a template has a different name within the
380context, you can alias it using the ``with`` argument of the :ttag:`include`
381tag::
382
383    <form action="/comments/add/" method="post">
384        {% include "form_snippet.html" with form=comment_form %}
385        <p><input type="submit" value="Submit comment" /></p>
386    </form>
387
388If you find yourself doing this often, you might consider creating a custom
389:ref:`inclusion tag<howto-custom-template-tags-inclusion-tags>`.
390
391Further topics
392==============
393
394This covers the basics, but forms can do a whole lot more:
395
396.. toctree::
397   :maxdepth: 2
398
399   formsets
400   modelforms
401   media
402
403.. seealso::
404
405    :doc:`The Forms Reference </ref/forms/index>`
406        Covers the full API reference, including form fields, form widgets,
407        and form and field validation.