Removed Form._errors from the docs in favor of the add_error API.
This commit is contained in:
parent
f563c339ca
commit
b72b85af15
|
@ -123,8 +123,7 @@ if validation has side effects, those side effects will only be triggered once.
|
||||||
|
|
||||||
This method allows adding errors to specific fields from within the
|
This method allows adding errors to specific fields from within the
|
||||||
``Form.clean()`` method, or from outside the form altogether; for instance
|
``Form.clean()`` method, or from outside the form altogether; for instance
|
||||||
from a view. This is a better alternative to fiddling directly with
|
from a view.
|
||||||
``Form._errors`` as described in :ref:`modifying-field-errors`.
|
|
||||||
|
|
||||||
The ``field`` argument is the name of the field to which the errors
|
The ``field`` argument is the name of the field to which the errors
|
||||||
should be added. If its value is ``None`` the error will be treated as
|
should be added. If its value is ``None`` the error will be treated as
|
||||||
|
|
|
@ -86,9 +86,8 @@ overridden:
|
||||||
be associated with any field in particular. They go into a special
|
be associated with any field in particular. They go into a special
|
||||||
"field" (called ``__all__``), which you can access via the
|
"field" (called ``__all__``), which you can access via the
|
||||||
``non_field_errors()`` method if you need to. If you want to attach
|
``non_field_errors()`` method if you need to. If you want to attach
|
||||||
errors to a specific field in the form, you will need to access the
|
errors to a specific field in the form, you need to call
|
||||||
``_errors`` attribute on the form, which is
|
:meth:`~django.forms.Form.add_error()`.
|
||||||
:ref:`described later <modifying-field-errors>`.
|
|
||||||
|
|
||||||
Also note that there are special considerations when overriding
|
Also note that there are special considerations when overriding
|
||||||
the ``clean()`` method of a ``ModelForm`` subclass. (see the
|
the ``clean()`` method of a ``ModelForm`` subclass. (see the
|
||||||
|
@ -202,52 +201,6 @@ with ``code``\s and ``params`` but a list of strings will also work::
|
||||||
_('Error 2'),
|
_('Error 2'),
|
||||||
])
|
])
|
||||||
|
|
||||||
.. _modifying-field-errors:
|
|
||||||
|
|
||||||
Form subclasses and modifying field errors
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
Sometimes, in a form's ``clean()`` method, you will want to add an error
|
|
||||||
message to a particular field in the form. This won't always be appropriate
|
|
||||||
and the more typical situation is to raise a ``ValidationError`` from
|
|
||||||
``Form.clean()``, which is turned into a form-wide error that is available
|
|
||||||
through the ``Form.non_field_errors()`` method.
|
|
||||||
|
|
||||||
When you really do need to attach the error to a particular field, you should
|
|
||||||
store (or amend) a key in the ``Form._errors`` attribute. This attribute is an
|
|
||||||
instance of a ``django.forms.utils.ErrorDict`` class. Essentially, though, it's
|
|
||||||
just a dictionary. There is a key in the dictionary for each field in the form
|
|
||||||
that has an error. Each value in the dictionary is a
|
|
||||||
``django.forms.utils.ErrorList`` instance, which is a list that knows how to
|
|
||||||
display itself in different ways. So you can treat ``_errors`` as a dictionary
|
|
||||||
mapping field names to lists.
|
|
||||||
|
|
||||||
If you want to add a new error to a particular field, you should check whether
|
|
||||||
the key already exists in ``self._errors`` or not. If not, create a new entry
|
|
||||||
for the given key, holding an empty ``ErrorList`` instance. In either case,
|
|
||||||
you can then append your error message to the list for the field name in
|
|
||||||
question and it will be displayed when the form is displayed.
|
|
||||||
|
|
||||||
There is an example of modifying ``self._errors`` in the following section.
|
|
||||||
|
|
||||||
.. admonition:: What's in a name?
|
|
||||||
|
|
||||||
You may be wondering why is this attribute called ``_errors`` and not
|
|
||||||
``errors``. Normal Python practice is to prefix a name with an underscore
|
|
||||||
if it's not for external usage. In this case, you are subclassing the
|
|
||||||
``Form`` class, so you are essentially writing new internals. In effect,
|
|
||||||
you are given permission to access some of the internals of ``Form``.
|
|
||||||
|
|
||||||
Of course, any code outside your form should never access ``_errors``
|
|
||||||
directly. The data is available to external code through the ``errors``
|
|
||||||
property, which populates ``_errors`` before returning it).
|
|
||||||
|
|
||||||
Another reason is purely historical: the attribute has been called
|
|
||||||
``_errors`` since the early days of the forms module and changing it now
|
|
||||||
(particularly since ``errors`` is used for the read-only property name)
|
|
||||||
would be inconvenient for a number of reasons. You can use whichever
|
|
||||||
explanation makes you feel more comfortable. The result is the same.
|
|
||||||
|
|
||||||
Using validation in practice
|
Using validation in practice
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
@ -366,6 +319,13 @@ write a cleaning method that operates on the ``recipients`` field, like so::
|
||||||
# not.
|
# not.
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
Sometimes you may want to add an error message to a particular field from the
|
||||||
|
form's ``clean()`` method, in which case you can use
|
||||||
|
:meth:`~django.forms.Form.add_error()`. Note that this won't always be
|
||||||
|
appropriate and the more typical situation is to raise a ``ValidationError``
|
||||||
|
from , which is turned into a form-wide error that is available through the
|
||||||
|
``Form.non_field_errors()`` method.
|
||||||
|
|
||||||
Cleaning and validating fields that depend on each other
|
Cleaning and validating fields that depend on each other
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -431,47 +391,6 @@ sample) looks like this::
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
class ContactForm(forms.Form):
|
|
||||||
# Everything as before.
|
|
||||||
...
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
cleaned_data = super(ContactForm, self).clean()
|
|
||||||
cc_myself = cleaned_data.get("cc_myself")
|
|
||||||
subject = cleaned_data.get("subject")
|
|
||||||
|
|
||||||
if cc_myself and subject and "help" not in subject:
|
|
||||||
# We know these are not in self._errors now (see discussion
|
|
||||||
# below).
|
|
||||||
msg = u"Must put 'help' in subject when cc'ing yourself."
|
|
||||||
self._errors["cc_myself"] = self.error_class([msg])
|
|
||||||
self._errors["subject"] = self.error_class([msg])
|
|
||||||
|
|
||||||
# These fields are no longer valid. Remove them from the
|
|
||||||
# cleaned data.
|
|
||||||
del cleaned_data["cc_myself"]
|
|
||||||
del cleaned_data["subject"]
|
|
||||||
|
|
||||||
As you can see, this approach requires a bit more effort, not withstanding the
|
|
||||||
extra design effort to create a sensible form display. The details are worth
|
|
||||||
noting, however. Firstly, earlier we mentioned that you might need to check if
|
|
||||||
the field name keys already exist in the ``_errors`` dictionary. In this case,
|
|
||||||
since we know the fields exist in ``self.cleaned_data``, they must have been
|
|
||||||
valid when cleaned as individual fields, so there will be no corresponding
|
|
||||||
entries in ``_errors``.
|
|
||||||
|
|
||||||
Secondly, once we have decided that the combined data in the two fields we are
|
|
||||||
considering aren't valid, we must remember to remove them from the
|
|
||||||
``cleaned_data``. `cleaned_data`` is present even if the form doesn't
|
|
||||||
validate, but it contains only field values that did validate.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.7
|
|
||||||
|
|
||||||
In lieu of manipulating ``_errors`` directly, it's now possible to add errors
|
|
||||||
to specific fields with :meth:`django.forms.Form.add_error()`::
|
|
||||||
|
|
||||||
from django import forms
|
|
||||||
|
|
||||||
class ContactForm(forms.Form):
|
class ContactForm(forms.Form):
|
||||||
# Everything as before.
|
# Everything as before.
|
||||||
...
|
...
|
||||||
|
@ -488,7 +407,5 @@ to specific fields with :meth:`django.forms.Form.add_error()`::
|
||||||
|
|
||||||
The second argument of ``add_error()`` can be a simple string, or preferably
|
The second argument of ``add_error()`` can be a simple string, or preferably
|
||||||
an instance of ``ValidationError``. See :ref:`raising-validation-error` for
|
an instance of ``ValidationError``. See :ref:`raising-validation-error` for
|
||||||
more details.
|
more details. Note that ``add_error()` automatically removes the field
|
||||||
|
|
||||||
Unlike the ``_errors`` approach, ``add_error()` automatically removes the field
|
|
||||||
from ``cleaned_data``.
|
from ``cleaned_data``.
|
||||||
|
|
Loading…
Reference in New Issue