Author: jkocherhans
Date: 2010-01-04 17:52:03 -0600 (Mon, 04 Jan 2010)
New Revision: 12091
Modified:
django/branches/soc2009/model-validation/docs/ref/forms/validation.txt
Log:
[soc2009/model-validation] Removed references in the docs to ComplexValidator.
Refs [12498].
Modified: django/branches/soc2009/model-validation/docs/ref/forms/validation.txt
===================================================================
--- django/branches/soc2009/model-validation/docs/ref/forms/validation.txt
2010-01-04 23:34:54 UTC (rev 12090)
+++ django/branches/soc2009/model-validation/docs/ref/forms/validation.txt
2010-01-04 23:52:03 UTC (rev 12091)
@@ -23,26 +23,11 @@
``ValidationError`` constructor.
Most validation can be done using `validators`_ - simple helpers that can be
-reused easily. There are two types of validators:
+reused easily. Validators are simple functions (or callables) that take a
single
+argument and raise ``ValidationError`` on invalid input. Validators are run
+inside the ``run_validators`` method that is called from ``Field.clean`` once
+the value is validated by the field's methods.
- * Simple validators are simple functions (or callables) that take a single
- argument and raises ``ValidationError`` on invalid input. Simple
- validators are run inside the ``run_validators`` method that is called
- from ``Field.clean`` once the value is validated by the field's methods.
-
- * Complex validators are instances of ``ComplexValidator`` class and,
- unlike simple validators, can access not just one value, but all at once.
- These are perfectly suited for cross field validation (one of N fields
- must be supplied, this field must equal that etc.)
-
-
-.. warning::
-
- Since complex validators must have access to all cleaned values, they must
- be run after individual fields have been cleaned. This means that these
are run
- in ``Form.full_clean`` and not inside ``Field.clean`` with simple
validators.
-
-
Validation of a Form is split into several steps, which can be customized or
overridden:
@@ -59,10 +44,10 @@
raises ``ValidationError`` on any error. This method does not return
anything and shouldn't alter the value.
- * Simple validators are run in the ``run_validators`` method. This method
+ * Validators are run in the ``run_validators`` method. This method
aggregates all the errors from all validators run into a single
``ValidationError``.
-
+
* The ``clean()`` method on a Field subclass. This is responsible for
running ``to_python``, ``validate`` and ``run_validators`` in the correct
order and propagate their errors. If, at any time, any of the methods
@@ -91,11 +76,6 @@
should return the cleaned data, regardless of whether it changed
anything or not.
- * The Field's complex validators are run after all the fields have been
- cleaned and only on those fields that passed validation. Errors from
- individual validators are aggregated and all the errors are raised for a
- given field.
-
* 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``
@@ -115,9 +95,8 @@
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 its override) is run, then
-``clean_<fieldname>()``. Once those two methods are run for every
-field, the complex validators are run for every field and, finally,
-``Form.clean()`` method, or its override, is executed.
+``clean_<fieldname>()``. Finally, once those two methods are run for every
+field, the ``Form.clean()`` method, or its override, is executed.
Examples of each of these methods are provided below.
@@ -293,49 +272,53 @@
Suppose we add another requirement to our contact form: if the ``cc_myself``
field is ``True``, the ``subject`` must contain the word ``"help"``. We are
-performing validation on more than one field at a time, so a
-``ComplexValidator`` is a good start. The complex validators are run in the
-form's ``clean()`` after the individual fields have been validated. This is the
-main difference against simple validators. It is important to realize that,
-even if defined in very similar way, simple and complex validators are run in
-different places in the code. Simple validators on a field (single data point),
-complex validator on a form (collection of fields).
+performing validation on more than one field at a time, so the form's
+``clean()`` method is a good spot to do this. Notice that we are talking about
+the ``clean()`` method on the form here, whereas earlier we were writing a
+``clean()`` method on a field. It's important to keep the field and form
+difference clear when working out where to validate things. Fields are single
+data points, forms are a collection of fields.
-By the time the field's complex validators are called, all the individual field
-clean methods will have been run (the previous two sections), so the
-validator's ``all_values`` argument will be populated with any data that has
-survived so far. So you also need to remember to allow for the fact that the
-fields you are wanting to validate might not have survived the initial
-individual field checks.
+By the time the form's ``clean()`` method is called, all the individual field
+clean methods will have been run (the previous two sections), so
+``self.cleaned_data`` will be populated with any data that has survived so
+far. So you also need to remember to allow for the fact that the fields you
+are wanting to validate might not have survived the initial individual field
+checks.
-Complex validator is run on the form, but reports it's error with the field. As
-with simple validators, all complex validators for a given field are run if the
-field has passed cleaning and their errors are aggregated and reported.
+There are two way to report any errors from this step. Probably the most
+common method is to display the error at the top of the form. To create such
+an error, you can raise a ``ValidationError`` from the ``clean()`` method. For
+example::
-To create a complex validator, simply subclass ``ComplexValidator`` and supply
-your validation logic in it's ``__call__()`` method, for example::
+ class ContactForm(forms.Form):
+ # Everything as before.
+ ...
- class ValidateHelpInSubjectIfCCingMyself(ComplexValidator):
- def __call__(self, all_values={}, obj=None):
- cc_myself = self.get_value('cc_myself', all_values, obj)
+ def clean(self):
+ cleaned_data = self.cleaned_data
+ cc_myself = cleaned_data.get("cc_myself")
+ subject = cleaned_data.get("subject")
- if cc_myself and "help" not in value:
- raise forms.ValidationError("Did not send for 'help' in "
- "the subject despite CC'ing yourself.")
-
+ if cc_myself and subject:
+ # Only do something if both fields are valid so far.
+ if "help" not in subject:
+ raise forms.ValidationError("Did not send for 'help' in "
+ "the subject despite CC'ing yourself.")
- class ContactForm(forms.Form):
- subject = forms.CharField(max_length=100,
- validators=[ValidateHelpInSubjectIfCCingMyself()])
- ...
- # Everything as before.
+ # Always return the full collection of cleaned data.
+ return cleaned_data
+In this code, if the validation error is raised, the form will display an
+error message at the top of the form (normally) describing the problem.
-The second approach might involve assigning the error message to both fields
-involved. To do this we will move the validation code to the form's ``clean()``
-method, which is a convenient place for form-wide validation and has access to
-the form instance and it's ``_errors`` property. Our new code (replacing the
-previous sample) looks like this::
+The second approach might involve assigning the error message to one of the
+fields. In this case, let's assign an error message to both the "subject" and
+"cc_myself" rows in the form display. Be careful when doing this in practice,
+since it can lead to confusing form output. We're showing what is possible
+here and leaving it up to you and your designers to work out what works
+effectively in your particular situation. Our new code (replacing the previous
+sample) looks like this::
from django.forms.util import ErrorList
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.