Reworked docs for ModelForm validation.
This commit is contained in:
parent
ce5c8a392f
commit
fba6c2ede7
|
@ -197,29 +197,89 @@ we'll discuss in a moment.)::
|
||||||
name = forms.CharField(max_length=100)
|
name = forms.CharField(max_length=100)
|
||||||
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
|
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
|
||||||
|
|
||||||
.. _modelform-is-valid-and-errors:
|
.. _validation-on-modelform:
|
||||||
|
|
||||||
The ``is_valid()`` method and ``errors``
|
Validation on a ``ModelForm``
|
||||||
----------------------------------------
|
-----------------------------
|
||||||
|
|
||||||
The first time you call ``is_valid()`` or access the ``errors`` attribute of a
|
There are two main steps involved in validating a ``ModelForm``:
|
||||||
``ModelForm`` triggers :ref:`form validation <form-and-field-validation>` as
|
|
||||||
well as :ref:`model validation <validating-objects>`. This has the side-effect
|
|
||||||
of cleaning the model you pass to the ``ModelForm`` constructor. For instance,
|
|
||||||
calling ``is_valid()`` on your form will convert any date fields on your model
|
|
||||||
to actual date objects. If form validation fails, only some of the updates
|
|
||||||
may be applied. For this reason, you'll probably want to avoid reusing the
|
|
||||||
model instance passed to the form, especially if validation fails.
|
|
||||||
|
|
||||||
|
1. :ref:`Validating the form <form-and-field-validation>`
|
||||||
|
2. :ref:`Validating the model instance <validating-objects>`
|
||||||
|
|
||||||
|
Just like normal form validation, model form validation is triggered implicitly
|
||||||
|
when calling :meth:`~django.forms.Form.is_valid()` or accessing the
|
||||||
|
:attr:`~django.forms.Form.errors` attribute and explicitly when calling
|
||||||
|
``full_clean()``, although you will typically not use the latter method in
|
||||||
|
practice.
|
||||||
|
|
||||||
|
``Model`` validation (:meth:`Model.full_clean()
|
||||||
|
<django.db.models.Model.full_clean()>`) is triggered from within the form
|
||||||
|
validation step, right after the form's ``clean()`` method is called.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The cleaning process modifies the model instance passed to the
|
||||||
|
``ModelForm`` constructor in various ways. For instance, any date fields on
|
||||||
|
the model are converted into actual date objects. Failed validation may
|
||||||
|
leave the underlying model instance in an inconsistent state and therefore
|
||||||
|
it's not recommended to reuse it.
|
||||||
|
|
||||||
|
.. _overriding-modelform-clean-method:
|
||||||
|
|
||||||
|
Overriding the clean() method
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
You can override the ``clean()`` method on a model form to provide additional
|
||||||
|
validation in the same way you can on a normal form.
|
||||||
|
|
||||||
|
A model form instance bound to a model object will contain an ``instance``
|
||||||
|
attribute that gives its methods access to that specific model instance.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The ``ModelForm.clean()`` method sets a flag that makes the :ref:`model
|
||||||
|
validation <validating-objects>` step validate the uniqueness of model
|
||||||
|
fields that are marked as ``unique``, ``unique_together`` or
|
||||||
|
``unique_for_date|month|year``.
|
||||||
|
|
||||||
|
If you would like to override the ``clean()`` method and maintain this
|
||||||
|
validation, you must call the parent class's ``clean()`` method.
|
||||||
|
|
||||||
|
Interaction with model validation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
As part of the validation process, ``ModelForm`` will call the ``clean()``
|
||||||
|
method of each field on your model that has a corresponding field on your form.
|
||||||
|
If you have excluded any model fields, validation will not be run on those
|
||||||
|
fields. See the :doc:`form validation </ref/forms/validation>` documentation
|
||||||
|
for more on how field cleaning and validation work.
|
||||||
|
|
||||||
|
The model's ``clean()`` method will be called before any uniqueness checks are
|
||||||
|
made. See :ref:`Validating objects <validating-objects>` for more information
|
||||||
|
on the model's ``clean()`` hook.
|
||||||
|
|
||||||
|
Considerations regarding fields' ``error_messages``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Error messages defined at the
|
||||||
|
:attr:`form field <django.forms.Field.error_messages>` level or at the
|
||||||
|
:ref:`form Meta <modelforms-overriding-default-fields>` level always take
|
||||||
|
precedence over the error messages defined at the
|
||||||
|
:attr:`model field <django.db.models.Field.error_messages>` level.
|
||||||
|
Error messages defined on :attr:`model fields
|
||||||
|
<django.db.models.Field.error_messages>` are only used when the
|
||||||
|
``ValidationError`` is raised during the :ref:`model validation
|
||||||
|
<validating-objects>` step and no corresponding error messages are defined at
|
||||||
|
the form level.
|
||||||
|
|
||||||
The ``save()`` method
|
The ``save()`` method
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Every form produced by ``ModelForm`` also has a ``save()``
|
Every ``ModelForm`` also has a ``save()`` method. This method creates and saves
|
||||||
method. This method creates and saves a database object from the data
|
a database object from the data bound to the form. A subclass of ``ModelForm``
|
||||||
bound to the form. A subclass of ``ModelForm`` can accept an existing
|
can accept an existing model instance as the keyword argument ``instance``; if
|
||||||
model instance as the keyword argument ``instance``; if this is
|
this is supplied, ``save()`` will update that instance. If it's not supplied,
|
||||||
supplied, ``save()`` will update that instance. If it's not supplied,
|
|
||||||
``save()`` will create a new instance of the specified model:
|
``save()`` will create a new instance of the specified model:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
@ -240,7 +300,7 @@ supplied, ``save()`` will update that instance. If it's not supplied,
|
||||||
>>> f.save()
|
>>> f.save()
|
||||||
|
|
||||||
Note that if the form :ref:`hasn't been validated
|
Note that if the form :ref:`hasn't been validated
|
||||||
<modelform-is-valid-and-errors>`, calling ``save()`` will do so by checking
|
<validation-on-modelform>`, calling ``save()`` will do so by checking
|
||||||
``form.errors``. A ``ValueError`` will be raised if the data in the form
|
``form.errors``. A ``ValueError`` will be raised if the data in the form
|
||||||
doesn't validate -- i.e., if ``form.errors`` evaluates to ``True``.
|
doesn't validate -- i.e., if ``form.errors`` evaluates to ``True``.
|
||||||
|
|
||||||
|
@ -263,7 +323,9 @@ exists in the database.
|
||||||
To work around this problem, every time you save a form using ``commit=False``,
|
To work around this problem, every time you save a form using ``commit=False``,
|
||||||
Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After
|
Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After
|
||||||
you've manually saved the instance produced by the form, you can invoke
|
you've manually saved the instance produced by the form, you can invoke
|
||||||
``save_m2m()`` to save the many-to-many form data. For example::
|
``save_m2m()`` to save the many-to-many form data. For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# Create a form instance with POST data.
|
# Create a form instance with POST data.
|
||||||
>>> f = AuthorForm(request.POST)
|
>>> f = AuthorForm(request.POST)
|
||||||
|
@ -283,7 +345,9 @@ you've manually saved the instance produced by the form, you can invoke
|
||||||
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
|
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
|
||||||
When you use a simple ``save()`` on a form, all data -- including
|
When you use a simple ``save()`` on a form, all data -- including
|
||||||
many-to-many data -- is saved without the need for any additional method calls.
|
many-to-many data -- is saved without the need for any additional method calls.
|
||||||
For example::
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
# Create a form instance with POST data.
|
# Create a form instance with POST data.
|
||||||
>>> a = Author()
|
>>> a = Author()
|
||||||
|
@ -537,27 +601,6 @@ attribute on the ``Meta`` class.
|
||||||
If ``localized_fields`` is set to the special value ``'__all__'``, all fields
|
If ``localized_fields`` is set to the special value ``'__all__'``, all fields
|
||||||
will be localized.
|
will be localized.
|
||||||
|
|
||||||
.. _overriding-modelform-clean-method:
|
|
||||||
|
|
||||||
Overriding the clean() method
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
You can override the ``clean()`` method on a model form to provide additional
|
|
||||||
validation in the same way you can on a normal form.
|
|
||||||
|
|
||||||
In this regard, model forms have two specific characteristics when compared to
|
|
||||||
forms:
|
|
||||||
|
|
||||||
By default the ``clean()`` method validates the uniqueness of fields that are
|
|
||||||
marked as ``unique``, ``unique_together`` or ``unique_for_date|month|year`` on
|
|
||||||
the model. Therefore, if you would like to override the ``clean()`` method and
|
|
||||||
maintain the default validation, you must call the parent class's ``clean()``
|
|
||||||
method.
|
|
||||||
|
|
||||||
Also, a model form instance bound to a model object will contain a
|
|
||||||
``self.instance`` attribute that gives model form methods access to that
|
|
||||||
specific model instance.
|
|
||||||
|
|
||||||
Form inheritance
|
Form inheritance
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -596,18 +639,6 @@ There are a couple of things to note, however.
|
||||||
Chances are these notes won't affect you unless you're trying to do something
|
Chances are these notes won't affect you unless you're trying to do something
|
||||||
tricky with subclassing.
|
tricky with subclassing.
|
||||||
|
|
||||||
Interaction with model validation
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
As part of its validation process, ``ModelForm`` will call the ``clean()``
|
|
||||||
method of each field on your model that has a corresponding field on your form.
|
|
||||||
If you have excluded any model fields, validation will not be run on those
|
|
||||||
fields. See the :doc:`form validation </ref/forms/validation>` documentation
|
|
||||||
for more on how field cleaning and validation work. Also, your model's
|
|
||||||
``clean()`` method will be called before any uniqueness checks are made. See
|
|
||||||
:ref:`Validating objects <validating-objects>` for more information on the
|
|
||||||
model's ``clean()`` hook.
|
|
||||||
|
|
||||||
.. _modelforms-factory:
|
.. _modelforms-factory:
|
||||||
|
|
||||||
ModelForm factory function
|
ModelForm factory function
|
||||||
|
|
Loading…
Reference in New Issue