Loading docs/topics/forms/modelforms.txt +83 −52 Original line number Diff line number Diff line Loading @@ -197,29 +197,89 @@ we'll discuss in a moment.):: name = forms.CharField(max_length=100) 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`` ----------------------------- There are two main steps involved in validating a ``ModelForm``: 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 first time you call ``is_valid()`` or access the ``errors`` attribute of a ``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. 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 --------------------- Every form produced by ``ModelForm`` also has a ``save()`` method. This method creates and saves a database object from the data bound to the form. A subclass of ``ModelForm`` can accept an existing model instance as the keyword argument ``instance``; if this is supplied, ``save()`` will update that instance. If it's not supplied, Every ``ModelForm`` also has a ``save()`` method. This method creates and saves a database object from the data bound to the form. A subclass of ``ModelForm`` can accept an existing model instance as the keyword argument ``instance``; if this is supplied, ``save()`` will update that instance. If it's not supplied, ``save()`` will create a new instance of the specified model: .. code-block:: python Loading @@ -240,7 +300,7 @@ supplied, ``save()`` will update that instance. If it's not supplied, >>> f.save() 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 doesn't validate -- i.e., if ``form.errors`` evaluates to ``True``. Loading @@ -263,7 +323,9 @@ exists in the database. 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 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. >>> f = AuthorForm(request.POST) Loading @@ -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)``. 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. For example:: For example: .. code-block:: python # Create a form instance with POST data. >>> a = Author() Loading Loading @@ -537,27 +601,6 @@ attribute on the ``Meta`` class. If ``localized_fields`` is set to the special value ``'__all__'``, all fields 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 ---------------- Loading Loading @@ -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 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: ModelForm factory function Loading Loading
docs/topics/forms/modelforms.txt +83 −52 Original line number Diff line number Diff line Loading @@ -197,29 +197,89 @@ we'll discuss in a moment.):: name = forms.CharField(max_length=100) 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`` ----------------------------- There are two main steps involved in validating a ``ModelForm``: 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 first time you call ``is_valid()`` or access the ``errors`` attribute of a ``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. 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 --------------------- Every form produced by ``ModelForm`` also has a ``save()`` method. This method creates and saves a database object from the data bound to the form. A subclass of ``ModelForm`` can accept an existing model instance as the keyword argument ``instance``; if this is supplied, ``save()`` will update that instance. If it's not supplied, Every ``ModelForm`` also has a ``save()`` method. This method creates and saves a database object from the data bound to the form. A subclass of ``ModelForm`` can accept an existing model instance as the keyword argument ``instance``; if this is supplied, ``save()`` will update that instance. If it's not supplied, ``save()`` will create a new instance of the specified model: .. code-block:: python Loading @@ -240,7 +300,7 @@ supplied, ``save()`` will update that instance. If it's not supplied, >>> f.save() 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 doesn't validate -- i.e., if ``form.errors`` evaluates to ``True``. Loading @@ -263,7 +323,9 @@ exists in the database. 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 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. >>> f = AuthorForm(request.POST) Loading @@ -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)``. 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. For example:: For example: .. code-block:: python # Create a form instance with POST data. >>> a = Author() Loading Loading @@ -537,27 +601,6 @@ attribute on the ``Meta`` class. If ``localized_fields`` is set to the special value ``'__all__'``, all fields 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 ---------------- Loading Loading @@ -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 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: ModelForm factory function Loading