summaryrefslogtreecommitdiff
path: root/docs/topics/forms/modelforms.txt
diff options
context:
space:
mode:
authorCarlton Gibson <carlton.gibson@noumenal.es>2023-02-09 16:48:46 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-02-10 19:19:13 +0100
commit534ac4829764f317cf2fbc4a18354fcc998c1425 (patch)
treec85c1df220ea6c3a87f9820106ba5a06e9ec9394 /docs/topics/forms/modelforms.txt
parent7bb741d787ba360a9f0d490db92e22e0d28204ed (diff)
Refs #34140 -- Applied rst code-block to non-Python examples.
Thanks to J.V. Zammit, Paolo Melchiorre, and Mariusz Felisiak for reviews.
Diffstat (limited to 'docs/topics/forms/modelforms.txt')
-rw-r--r--docs/topics/forms/modelforms.txt116
1 files changed, 84 insertions, 32 deletions
diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index 253a4a01a4..4242cd96e0 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -17,7 +17,9 @@ you've already defined the fields in your model.
For this reason, Django provides a helper class that lets you create a ``Form``
class from a Django model.
-For example::
+For example:
+
+.. code-block:: pycon
>>> from django.forms import ModelForm
>>> from myapp.models import Article
@@ -320,7 +322,9 @@ 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::
+``save()`` will create a new instance of the specified model:
+
+.. code-block:: pycon
>>> from myapp.models import Article
>>> from myapp.forms import ArticleForm
@@ -373,7 +377,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:: pycon
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)
@@ -392,7 +398,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 ``save()`` on a form, all data -- including many-to-many data --
-is saved without the need for any additional method calls. For example::
+is saved without the need for any additional method calls. For example:
+
+.. code-block:: pycon
# Create a form instance with POST data.
>>> a = Author()
@@ -680,7 +688,9 @@ Form inheritance
As with basic forms, you can extend and reuse ``ModelForms`` by inheriting
them. This is useful if you need to declare extra fields or extra methods on a
parent class for use in a number of forms derived from models. For example,
-using the previous ``ArticleForm`` class::
+using the previous ``ArticleForm`` class:
+
+.. code-block:: pycon
>>> class EnhancedArticleForm(ArticleForm):
... def clean_pub_date(self):
@@ -690,7 +700,9 @@ This creates a form that behaves identically to ``ArticleForm``, except there's
some extra validation and cleaning for the ``pub_date`` field.
You can also subclass the parent's ``Meta`` inner class if you want to change
-the ``Meta.fields`` or ``Meta.exclude`` lists::
+the ``Meta.fields`` or ``Meta.exclude`` lists:
+
+.. code-block:: pycon
>>> class RestrictedArticleForm(EnhancedArticleForm):
... class Meta(ArticleForm.Meta):
@@ -725,7 +737,9 @@ Providing initial values
As with regular forms, it's possible to specify initial data for forms by
specifying an ``initial`` parameter when instantiating the form. Initial
values provided this way will override both initial values from the form field
-and values from an attached model instance. For example::
+and values from an attached model instance. For example:
+
+.. code-block:: pycon
>>> article = Article.objects.get(pk=1)
>>> article.headline
@@ -742,14 +756,18 @@ ModelForm factory function
You can create forms from a given model using the standalone function
:func:`~django.forms.models.modelform_factory`, instead of using a class
definition. This may be more convenient if you do not have many customizations
-to make::
+to make:
+
+.. code-block:: pycon
>>> from django.forms import modelform_factory
>>> from myapp.models import Book
>>> BookForm = modelform_factory(Book, fields=["author", "title"])
This can also be used to make modifications to existing forms, for example by
-specifying the widgets to be used for a given field::
+specifying the widgets to be used for a given field:
+
+.. code-block:: pycon
>>> from django.forms import Textarea
>>> Form = modelform_factory(Book, form=BookForm,
@@ -773,7 +791,9 @@ Model formsets
Like :doc:`regular formsets </topics/forms/formsets>`, Django provides a couple
of enhanced formset classes to make working with Django models more
-convenient. Let's reuse the ``Author`` model from above::
+convenient. Let's reuse the ``Author`` model from above:
+
+.. code-block:: pycon
>>> from django.forms import modelformset_factory
>>> from myapp.models import Author
@@ -781,12 +801,16 @@ convenient. Let's reuse the ``Author`` model from above::
Using ``fields`` restricts the formset to use only the given fields.
Alternatively, you can take an "opt-out" approach, specifying which fields to
-exclude::
+exclude:
+
+.. code-block:: pycon
>>> AuthorFormSet = modelformset_factory(Author, exclude=['birth_date'])
This will create a formset that is capable of working with the data associated
-with the ``Author`` model. It works just like a regular formset::
+with the ``Author`` model. It works just like a regular formset:
+
+.. code-block:: pycon
>>> formset = AuthorFormSet()
>>> print(formset)
@@ -818,7 +842,9 @@ Changing the queryset
By default, when you create a formset from a model, the formset will use a
queryset that includes all objects in the model (e.g.,
``Author.objects.all()``). You can override this behavior by using the
-``queryset`` argument::
+``queryset`` argument:
+
+.. code-block:: pycon
>>> formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O'))
@@ -833,13 +859,17 @@ Alternatively, you can create a subclass that sets ``self.queryset`` in
super().__init__(*args, **kwargs)
self.queryset = Author.objects.filter(name__startswith='O')
-Then, pass your ``BaseAuthorFormSet`` class to the factory function::
+Then, pass your ``BaseAuthorFormSet`` class to the factory function:
+
+.. code-block:: pycon
>>> AuthorFormSet = modelformset_factory(
... Author, fields=['name', 'title'], formset=BaseAuthorFormSet)
If you want to return a formset that doesn't include *any* preexisting
-instances of the model, you can specify an empty QuerySet::
+instances of the model, you can specify an empty QuerySet:
+
+.. code-block:: pycon
>>> AuthorFormSet(queryset=Author.objects.none())
@@ -874,7 +904,9 @@ Specifying widgets to use in the form with ``widgets``
Using the ``widgets`` parameter, you can specify a dictionary of values to
customize the ``ModelForm``’s widget class for a particular field. This
works the same way as the ``widgets`` dictionary on the inner ``Meta``
-class of a ``ModelForm`` works::
+class of a ``ModelForm`` works:
+
+.. code-block:: pycon
>>> AuthorFormSet = modelformset_factory(
... Author, fields=['name', 'title'],
@@ -912,7 +944,9 @@ Saving objects in the formset
-----------------------------
As with a ``ModelForm``, you can save the data as a model object. This is done
-with the formset's ``save()`` method::
+with the formset's ``save()`` method:
+
+.. code-block:: pycon
# Create a formset instance with POST data.
>>> formset = AuthorFormSet(request.POST)
@@ -930,7 +964,9 @@ excluded), these fields will not be set by the ``save()`` method. You can find
more information about this restriction, which also holds for regular
``ModelForms``, in `Selecting the fields to use`_.
-Pass ``commit=False`` to return the unsaved model instances::
+Pass ``commit=False`` to return the unsaved model instances:
+
+.. code-block:: pycon
# don't save to the database
>>> instances = formset.save(commit=False)
@@ -959,7 +995,9 @@ As with regular formsets, you can use the ``max_num`` and ``extra`` parameters
to :func:`~django.forms.models.modelformset_factory` to limit the number of
extra forms displayed.
-``max_num`` does not prevent existing objects from being displayed::
+``max_num`` does not prevent existing objects from being displayed:
+
+.. code-block:: pycon
>>> Author.objects.order_by('name')
<QuerySet [<Author: Charles Baudelaire>, <Author: Paul Verlaine>, <Author: Walt Whitman>]>
@@ -976,7 +1014,9 @@ this.
If the value of ``max_num`` is greater than the number of existing related
objects, up to ``extra`` additional blank forms will be added to the formset,
-so long as the total number of forms does not exceed ``max_num``::
+so long as the total number of forms does not exceed ``max_num``:
+
+.. code-block:: pycon
>>> AuthorFormSet = modelformset_factory(Author, fields=['name'], max_num=4, extra=2)
>>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
@@ -996,7 +1036,9 @@ Preventing new objects creation
-------------------------------
Using the ``edit_only`` parameter, you can prevent creation of any new
-objects::
+objects:
+
+.. code-block:: pycon
>>> AuthorFormSet = modelformset_factory(
... Author,
@@ -1104,18 +1146,20 @@ cases in this example.
Using the formset in the template
---------------------------------
-.. highlight:: html+django
-
There are three ways to render a formset in a Django template.
-First, you can let the formset do most of the work::
+First, you can let the formset do most of the work:
+
+.. code-block:: html+django
<form method="post">
{{ formset }}
</form>
Second, you can manually render the formset, but let the form deal with
-itself::
+itself:
+
+.. code-block:: html+django
<form method="post">
{{ formset.management_form }}
@@ -1128,7 +1172,9 @@ When you manually render the forms yourself, be sure to render the management
form as shown above. See the :ref:`management form documentation
<understanding-the-managementform>`.
-Third, you can manually render each field::
+Third, you can manually render each field:
+
+.. code-block:: html+django
<form method="post">
{{ formset.management_form }}
@@ -1141,7 +1187,9 @@ Third, you can manually render each field::
If you opt to use this third method and you don't iterate over the fields with
a ``{% for %}`` loop, you'll need to render the primary key field. For example,
-if you were rendering the ``name`` and ``age`` fields of a model::
+if you were rendering the ``name`` and ``age`` fields of a model:
+
+.. code-block:: html+django
<form method="post">
{{ formset.management_form }}
@@ -1159,8 +1207,6 @@ the model formset, in the ``POST`` case, will work correctly. (This example
assumes a primary key named ``id``. If you've explicitly defined your own
primary key that isn't called ``id``, make sure it gets rendered.)
-.. highlight:: python
-
.. _inline-formsets:
Inline formsets
@@ -1182,7 +1228,9 @@ you have these two models::
title = models.CharField(max_length=100)
If you want to create a formset that allows you to edit books belonging to
-a particular author, you could do this::
+a particular author, you could do this:
+
+.. code-block:: pycon
>>> from django.forms import inlineformset_factory
>>> BookFormSet = inlineformset_factory(Author, Book, fields=['title'])
@@ -1225,7 +1273,9 @@ For example, if you want to override ``clean()``::
See also :ref:`model-formsets-overriding-clean`.
Then when you create your inline formset, pass in the optional argument
-``formset``::
+``formset``:
+
+.. code-block:: pycon
>>> from django.forms import inlineformset_factory
>>> BookFormSet = inlineformset_factory(Author, Book, fields=['title'],
@@ -1254,7 +1304,9 @@ the following model::
length_in_months = models.IntegerField()
To resolve this, you can use ``fk_name`` to
-:func:`~django.forms.models.inlineformset_factory`::
+:func:`~django.forms.models.inlineformset_factory`:
+
+.. code-block:: pycon
>>> FriendshipFormSet = inlineformset_factory(Friend, Friendship, fk_name='from_friend',
... fields=['to_friend', 'length_in_months'])