mirror of
https://github.com/django/django.git
synced 2025-07-06 18:59:13 +00:00
[soc2009/model-validation] Removed references in the docs to ComplexValidator. Refs [12498].
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@12091 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
82c4f9d04e
commit
1f98e98106
@ -23,25 +23,10 @@ of them to the form submitter, it is possible to pass a list of errors to the
|
||||
``ValidationError`` constructor.
|
||||
|
||||
Most validation can be done using `validators`_ - simple helpers that can be
|
||||
reused easily. There are two types of validators:
|
||||
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
Validation of a Form is split into several steps, which can be customized or
|
||||
overridden:
|
||||
@ -59,10 +44,10 @@ overridden:
|
||||
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 @@ overridden:
|
||||
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 @@ overridden:
|
||||
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 @@ Cleaning and validating fields that depend on each other
|
||||
|
||||
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.
|
||||
|
||||
To create a complex validator, simply subclass ``ComplexValidator`` and supply
|
||||
your validation logic in it's ``__call__()`` method, for example::
|
||||
|
||||
class ValidateHelpInSubjectIfCCingMyself(ComplexValidator):
|
||||
def __call__(self, all_values={}, obj=None):
|
||||
cc_myself = self.get_value('cc_myself', all_values, obj)
|
||||
|
||||
if cc_myself and "help" not in value:
|
||||
raise forms.ValidationError("Did not send for 'help' in "
|
||||
"the subject despite CC'ing yourself.")
|
||||
|
||||
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::
|
||||
|
||||
class ContactForm(forms.Form):
|
||||
subject = forms.CharField(max_length=100,
|
||||
validators=[ValidateHelpInSubjectIfCCingMyself()])
|
||||
...
|
||||
# Everything as before.
|
||||
...
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = self.cleaned_data
|
||||
cc_myself = cleaned_data.get("cc_myself")
|
||||
subject = cleaned_data.get("subject")
|
||||
|
||||
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::
|
||||
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.")
|
||||
|
||||
# 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 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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user