diff options
Diffstat (limited to 'parts/django/docs/topics/forms/index.txt')
-rw-r--r-- | parts/django/docs/topics/forms/index.txt | 402 |
1 files changed, 0 insertions, 402 deletions
diff --git a/parts/django/docs/topics/forms/index.txt b/parts/django/docs/topics/forms/index.txt deleted file mode 100644 index 30b09c0..0000000 --- a/parts/django/docs/topics/forms/index.txt +++ /dev/null @@ -1,402 +0,0 @@ -================== -Working with forms -================== - -.. admonition:: About this document - - This document provides an introduction to Django's form handling features. - 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`. - -.. highlightlang:: html+django - -``django.forms`` is Django's form-handling library. - -While it is possible to process form submissions just using Django's -:class:`~django.http.HttpRequest` class, using the form library takes care of a -number of common form-related tasks. Using it, you can: - - 1. Display an HTML form with automatically generated form widgets. - 2. Check submitted data against a set of validation rules. - 3. Redisplay a form in the case of validation errors. - 4. Convert submitted form data to the relevant Python data types. - -Overview -======== - -The library deals with these concepts: - -.. glossary:: - - 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 e-mail 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: - -.. code-block:: python - - from django import forms - - 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 :doc:`/ref/forms/fields`. - -If your form is going to be used to directly add or edit a Django model, you can -use a :doc:`ModelForm </topics/forms/modelforms>` to avoid duplicating your model -description. - -Using a form in a view ----------------------- - -The standard pattern for processing a form in a view looks like this: - -.. code-block:: python - - 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, - }) - - -There are three code paths here: - - 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. - -.. versionchanged:: 1.0 - The ``cleaned_data`` attribute was called ``clean_data`` in earlier releases. - -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 :ref:`ref-forms-api-bound-unbound` for further information on the -differences between bound and unbound forms. - -Handling file uploads with a form ---------------------------------- - -To see how to handle file uploads with your form see -:ref:`binding-uploaded-files` for more information. - -Processing the data from a form -------------------------------- - -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. - -Extending the above example, here's how the form data could be processed: - -.. code-block:: python - - 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) - - from django.core.mail import send_mail - send_mail(subject, message, sender, recipients) - return HttpResponseRedirect('/thanks/') # Redirect after POST - -For more on sending e-mail from Django, see :doc:`/topics/email`. - -Displaying a form using a template ----------------------------------- - -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:: - - <form action="/contact/" method="post"> - {{ form.as_p }} - <input type="submit" value="Submit" /> - </form> - -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:: - - <form action="/contact/" method="post"> - <p><label for="id_subject">Subject:</label> - <input id="id_subject" type="text" name="subject" maxlength="100" /></p> - <p><label for="id_message">Message:</label> - <input type="text" name="message" id="id_message" /></p> - <p><label for="id_sender">Sender:</label> - <input type="text" name="sender" id="id_sender" /></p> - <p><label for="id_cc_myself">Cc myself:</label> - <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p> - <input type="submit" value="Submit" /> - </form> - -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 :ref:`customize the way in which labels and ids are generated -<ref-forms-api-configuring-label>`. - -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. - -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:: - - <form action="/contact/" method="post"> - {{ form.non_field_errors }} - <div class="fieldWrapper"> - {{ form.subject.errors }} - <label for="id_subject">E-mail subject:</label> - {{ form.subject }} - </div> - <div class="fieldWrapper"> - {{ form.message.errors }} - <label for="id_message">Your message:</label> - {{ form.message }} - </div> - <div class="fieldWrapper"> - {{ form.sender.errors }} - <label for="id_sender">Your email address:</label> - {{ form.sender }} - </div> - <div class="fieldWrapper"> - {{ form.cc_myself.errors }} - <label for="id_cc_myself">CC yourself?</label> - {{ form.cc_myself }} - </div> - <p><input type="submit" value="Send message" /></p> - </form> - -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 %} - -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:: - - <form action="/contact/" method="post"> - {% for field in form %} - <div class="fieldWrapper"> - {{ field.errors }} - {{ field.label_tag }}: {{ field }} - </div> - {% endfor %} - <p><input type="submit" value="Send message" /></p> - </form> - -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. ``E-mail address``. - - ``{{ field.label_tag }}`` - The field's label wrapped in the appropriate HTML ``<label>`` tag, - e.g. ``<label for="id_email">E-mail 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 %} - -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 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:: - - <form action="/contact/" method="post"> - {% for field in form.visible_fields %} - <div class="fieldWrapper"> - - {# Include the hidden fields in the form #} - {% if forloop.first %} - {% for hidden in form.hidden_fields %} - {{ hidden }} - {% endfor %} - {% endif %} - - {{ 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. - -.. versionadded:: 1.1 - The ``hidden_fields`` and ``visible_fields`` methods are new in Django - 1.1. - -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:: - - <form action="/contact/" method="post"> - {% include "form_snippet.html" %} - <p><input type="submit" value="Send message" /></p> - </form> - - # 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 :ttag:`with` tag:: - - <form action="/comments/add/" method="post"> - {% with comment_form as form %} - {% include "form_snippet.html" %} - {% endwith %} - <p><input type="submit" value="Submit comment" /></p> - </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 - - modelforms - formsets - media - -.. seealso:: - - :doc:`The Forms Reference </ref/forms/index>` - Covers the full API reference, including form fields, form widgets, - and form and field validation. |