summaryrefslogtreecommitdiff
path: root/docs/newforms.txt
diff options
context:
space:
mode:
authorAdrian Holovaty <adrian@holovaty.com>2006-12-27 02:49:28 +0000
committerAdrian Holovaty <adrian@holovaty.com>2006-12-27 02:49:28 +0000
commit0cf7bc439129c66df8d64601e885f83b256b4f25 (patch)
treea7fd3cd4df5e862578544778d1b720ded59b7274 /docs/newforms.txt
parentc4673e4fb68237f96652d7372bec0283c5446c27 (diff)
per-object-permissions: Merged to trunk [4241]
git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@4242 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs/newforms.txt')
-rw-r--r--docs/newforms.txt300
1 files changed, 300 insertions, 0 deletions
diff --git a/docs/newforms.txt b/docs/newforms.txt
new file mode 100644
index 0000000000..c4986eb45e
--- /dev/null
+++ b/docs/newforms.txt
@@ -0,0 +1,300 @@
+====================
+The newforms library
+====================
+
+``django.newforms`` is a new replacement for ``django.forms``, the old Django
+form/manipulator/validation framework. This document explains how to use this
+new form library.
+
+Migration plan
+==============
+
+``django.newforms`` currently is only available in the Django development version
+-- i.e., it's not available in the Django 0.95 release. For the next Django
+release, our plan is to do the following:
+
+ * As of revision [4208], we've copied the current ``django.forms`` to
+ ``django.oldforms``. This allows you to upgrade your code *now* rather
+ than waiting for the backwards-incompatible change and rushing to fix
+ your code after the fact. Just change your import statements like this::
+
+ from django import forms # old
+ from django import oldforms as forms # new
+
+ * At an undecided future date, we will move the current ``django.newforms``
+ to ``django.forms``. This will be a backwards-incompatible change, and
+ anybody who is still using the old version of ``django.forms`` at that
+ time will need to change their import statements, as described in the
+ previous bullet.
+
+ * We will remove ``django.oldforms`` in the release *after* the next Django
+ release -- the release that comes after the release in which we're
+ creating the new ``django.forms``.
+
+With this in mind, we recommend you use the following import statement when
+using ``django.newforms``::
+
+ from django import newforms as forms
+
+This way, your code can refer to the ``forms`` module, and when
+``django.newforms`` is renamed to ``django.forms``, you'll only have to change
+your ``import`` statements.
+
+If you prefer "``import *``" syntax, you can do the following::
+
+ from django.newforms import *
+
+This will import all fields, widgets, form classes and other various utilities
+into your local namespace. Some people find this convenient; others find it
+too messy. The choice is yours.
+
+Overview
+========
+
+As the ``django.forms`` ("manipulators") system before it, ``django.newforms``
+is intended to handle HTML form display, validation and redisplay. It's what
+you use if you want to perform server-side validation for an HTML form.
+
+For example, if your Web site has a contact form that visitors can use to
+send you e-mail, you'd use this library to implement the display of the HTML
+form fields, along with the form validation. Any time you need to use an HTML
+``<form>``, you can use this library.
+
+The library deals with these concepts:
+
+ * **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 objects
+============
+
+The primary way of using the ``newforms`` library is to create a form object.
+Do this by subclassing ``django.newforms.Form`` and specifying the form's
+fields, in a declarative style that you'll be familiar with if you've used
+Django database models. In this section, we'll iteratively develop a form
+object that you might to implement "contact me" functionality on your personal
+Web site.
+
+Start with this basic ``Form`` subclass, which we'll call ``ContactForm``::
+
+ from django import newforms as forms
+
+ class ContactForm(forms.Form):
+ subject = forms.CharField(max_length=100)
+ message = forms.CharField()
+ sender = forms.EmailField()
+ cc_myself = forms.BooleanField()
+
+A form is composed of ``Field`` objects. In this case, our form has four
+fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. We'll explain
+the different types of fields -- e.g., ``CharField`` and ``EmailField`` --
+shortly.
+
+Outputting forms as HTML
+------------------------
+
+The first thing we can do with this is output it as HTML. To do so, instantiate
+it and ``print`` it::
+
+ >>> f = ContactForm()
+ >>> print f
+ <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+ <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+ <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+
+This default output is a two-column HTML table, with a ``<tr>`` for each field.
+Notice the following:
+
+ * For flexibility, the output does *not* include the ``<table>`` and
+ ``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
+ tags or an ``<input type="submit">`` tag. It's your job to do that.
+
+ * Each field type has a default HTML representation. ``CharField`` and
+ ``EmailField`` are represented by an ``<input type="text">``.
+ ``BooleanField`` is represented by an ``<input type="checkbox">``. Note
+ these are merely sensible defaults; you can specify which HTML to use for
+ a given field by using ``widgets``, which we'll explain shortly.
+
+ * The HTML ``name`` for each tag is taken directly from its attribute name
+ in the ``ContactForm`` class.
+
+ * The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
+ ``'CC myself:'`` is generated from the field name by converting all
+ underscores to spaces and upper-casing the first letter. Again, note
+ these are merely sensible defaults; you can also specify labels manually.
+
+ * Each text label is surrounded in an HTML ``<label>`` tag, which points
+ to the appropriate form field via its ``id``. Its ``id``, in turn, is
+ generated by prepending ``'id_'`` to the field name. The ``id``
+ attributes and ``<label>`` tags are included in the output by default, to
+ follow best practices, but you can change that behavior.
+
+Although ``<table>`` output is the default output style when you ``print`` a
+form, other output styles are available. Each style is available as a method on
+a form object, and each rendering method returns a Unicode object.
+
+``as_p()``
+~~~~~~~~~~
+
+``Form.as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
+containing one field::
+
+ >>> f = ContactForm()
+ >>> f.as_p()
+ u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
+ >>> print f.as_p()
+ <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>
+
+``as_ul()``
+~~~~~~~~~~~
+
+``Form.as_ul()`` renders the form as a series of ``<li>`` tags, with each
+``<li>`` containing one field. It does *not* include the ``<ul>`` or ``</ul>``,
+so that you can specify any HTML attributes on the ``<ul>`` for flexibility::
+
+ >>> f = ContactForm()
+ >>> f.as_ul()
+ u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
+ >>> print f.as_ul()
+ <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
+ <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
+ <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
+
+``as_table()``
+~~~~~~~~~~~~~~
+
+Finally, ``Form.as_table()`` outputs the form as an HTML ``<table>``. This is
+exactly the same as ``print``. In fact, when you ``print`` a form object, it
+calls its ``as_table()`` method behind the scenes::
+
+ >>> f = ContactForm()
+ >>> f.as_table()
+ u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
+ >>> print f.as_table()
+ <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+ <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+ <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+
+Configuring HTML ``<label>`` tags
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An HTML ``<label>`` tag designates which label text is associated with which
+form element. This small enhancement makes forms more usable and more accessible
+to assistive devices. It's always a good idea to use ``<label>`` tags.
+
+By default, the form rendering methods include HTML ``id`` attributes on the
+form elements and corresponding ``<label>`` tags around the labels. The ``id``
+attribute values are generated by prepending ``id_`` to the form field names.
+This behavior is configurable, though, if you want to change the ``id``
+convention or remove HTML ``id`` attributes and ``<label>`` tags entirely.
+
+Use the ``auto_id`` argument to the ``Form`` constructor to control the label
+and ``id`` behavior. This argument must be ``True``, ``False`` or a string.
+
+If ``auto_id`` is ``False``, then the form output will not include ``<label>``
+tags nor ``id`` attributes::
+
+ >>> f = ContactForm(auto_id=False)
+ >>> print f.as_table()
+ <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
+ <tr><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
+ <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
+ <li>Message: <input type="text" name="message" /></li>
+ <li>Sender: <input type="text" name="sender" /></li>
+ <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
+ >>> print f.as_p()
+ <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
+ <p>Message: <input type="text" name="message" /></p>
+ <p>Sender: <input type="text" name="sender" /></p>
+ <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
+
+If ``auto_id`` is set to ``True``, then the form output *will* include
+``<label>`` tags and will simply use the field name as its ``id`` for each form
+field::
+
+ >>> f = ContactForm(auto_id=True)
+ >>> print f.as_table()
+ <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
+ <tr><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
+ <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
+ <li><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
+ <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
+ >>> print f.as_p()
+ <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
+ <p><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
+ <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
+
+If ``auto_id`` is set to a string containing the format character ``'%s'``,
+then the form output will include ``<label>`` tags, and will generate ``id``
+attributes based on the format string. For example, for a format string
+``'field_%s'``, a field named ``subject`` will get the ``id``
+``'field_subject'``. Continuing our example::
+
+ >>> f = ContactForm(auto_id='id_for_%s')
+ >>> print f.as_table()
+ <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
+ <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
+ <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
+ <li><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
+ <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
+ >>> print f.as_p()
+ <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
+ <p><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
+ <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
+
+If ``auto_id`` is set to any other true value -- such as a string that doesn't
+include ``%s`` -- then the library will act as if ``auto_id`` is ``True``.
+
+By default, ``auto_id`` is set to the string ``'id_%s'``.
+
+Notes on field ordering
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In the ``as_p()``, ``as_ul()`` and ``as_table()`` shortcuts, the fields are
+displayed in the order in which you define them in your form class. For
+example, in the ``ContactForm`` example, the fields are defined in the order
+``subject``, ``message``, ``sender``, ``cc_myself``. To reorder the HTML
+output, just change the order in which those fields are listed in the class.
+
+More coming soon
+================
+
+That's all the documentation for now. For more, see the file
+http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py
+-- the unit tests for ``django.newforms``. This can give you a good idea of
+what's possible.
+
+Using forms to validate data
+----------------------------
+
+Using forms with templates
+==========================
+
+Using forms in views
+====================