Skip to content

Commit

Permalink
Fixed #4473 -- Added documentation of the three cleaning methods invo…
Browse files Browse the repository at this point in the history
…ked on

form data. Based on a patch from Joe Heck.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@5460 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Jun 11, 2007
1 parent 04f5bd4 commit 5c34684
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions docs/newforms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ is -- e.g., for ``DateField``, it's ``None`` instead of the empty string. For
full details on each field's behavior in this case, see the "Empty value" note
for each field in the "Built-in ``Field`` classes" section below.

You can write code to perform validation for particular form fields (based on
their name) or for the form as a whole (considering combinations of various
fields). More information about this is in the `Custom form and field
validation`_ section, below.

Behavior of unbound forms
~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -1212,6 +1217,84 @@ custom ``Field`` classes. To do this, just create a subclass of
mentioned above (``required``, ``label``, ``initial``, ``widget``,
``help_text``).

Custom form and field validation
---------------------------------

Form validation happens when the data is cleaned. If you want to customise
this process, there are various places you can change, each one serving a
different purpose. Thee types of cleaning methods are run during form
processing. These are normally executed when you call the ``is_valid()``
method on a form. There are other things that can kick of cleaning and
validation (accessing the ``errors`` attribute or calling ``full_clean()``
directly), but normally they won't be needed.

In general, any cleaning method can raise ``ValidationError`` if there is a
problem with the data it is processing, passing the relevant error message to
the ``ValidationError`` constructor. If no ``ValidationError`` is raised, the
method should return the cleaned (normalised) data as a Python object.

If you detect multiple errors during a cleaning method and wish to signal all
of them to the form submittor, it is possible to pass a list of errors to the
``ValidationError`` constructor.

The three types of cleaning methods are:

* The ``clean()`` method on a Field subclass. This is responsible
for cleaning the data in a way that is generic for that type of field.
For example, a FloatField will turn the data into a Python ``float`` or
raise a ``ValidationError``.

* The ``clean_<fieldname>()`` method in a form subclass -- where
``<fieldname>`` is replaced with the name of the form field attribute.
This method does any cleaning that is specific to that particular
attribute, unrelated to the type of field that it is. This method is not
passed any parameters. You will need to look up the value of the field
in ``self.cleaned_data`` and remember that it will be a Python object
at this point, not the original string submitted in the form (it will be
in ``cleaned_data`` because the general field ``clean()`` method, above,
has already cleaned the data once).

For example, if you wanted to validate that the contents of a
``CharField`` called ``serialnumber`` was unique,
``clean_serialnumber()`` would be the right place to do this. You don't
need a specific field (it's just a ``CharField``), but you want a
formfield-specific piece of validation and, possibly,
cleaning/normalizing the data.

* The Form subclass's ``clean()`` method. This method can perform
any validation that requires access to multiple fields from the form at
once. This is where you might put in things to check that if field ``A``
is supplied, field ``B`` must contain a valid email address and the
like. The data that this method returns is the final ``cleaned_data``
attribute for the form, so don't forget to return the full list of
cleaned data if you override this method (by default, ``Form.clean()``
just returns ``self.cleaned_data``).

Note that any errors raised by your ``Form.clean()`` override will not
be associated with any field in particular. They go into a special
"field" (called ``__all__``, which you can access via the
``non_field_errors()`` method if you need to.

These methods are run in the order given above, one field at a time. That is,
for each field in the form (in the order they are declared in the form
definition), the ``Field.clean()`` method (or it's override) is run, then
``clean_<fieldname>()``. Finally, once those two methods are run for every
field, the ``Form.clean()`` method, or it's override, is executed.

As mentioned above, any of these methods can raise a ``ValidationError``. For
any field, if the ``Field.clean()`` method raises a ``ValidationError``, any
field-specific cleaning method is not called. However, the cleaning methods
for all remaining fields are still executed.

The ``clean()`` method for the ``Form`` class or subclass is always run. If
that method raises a ``ValidationError``, ``cleaned_data`` will be an empty
dictionary.

The previous paragraph means that if you are overriding ``Form.clean()``, you
should iterate through ``self.cleaned_data.items()``, possibly considering the
``_errors`` dictionary attribute on the form as well. In this way, you will
already know which fields have passed thei individual validation requirements.

A simple example
~~~~~~~~~~~~~~~~

Expand Down

0 comments on commit 5c34684

Please sign in to comment.