summaryrefslogtreecommitdiff
path: root/docs/topics/forms
diff options
context:
space:
mode:
authorDavid Smith <smithdc@gmail.com>2021-09-10 08:06:01 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-20 15:50:18 +0200
commit456466d932830b096d39806e291fe23ec5ed38d5 (patch)
tree9320cc645ef43eb920630cff02c1387b34f21906 /docs/topics/forms
parent5353e7c2505c0d0ab8232ad9c131b3c99c833988 (diff)
Fixed #31026 -- Switched form rendering to template engine.
Thanks Carlton Gibson, Keryn Knight, Mariusz Felisiak, and Nick Pope for reviews. Co-authored-by: Johannes Hoppe <info@johanneshoppe.com>
Diffstat (limited to 'docs/topics/forms')
-rw-r--r--docs/topics/forms/formsets.txt95
-rw-r--r--docs/topics/forms/index.txt24
2 files changed, 108 insertions, 11 deletions
diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt
index 30979edae4..e15f11dea0 100644
--- a/docs/topics/forms/formsets.txt
+++ b/docs/topics/forms/formsets.txt
@@ -775,9 +775,92 @@ But with ``ArticleFormset(prefix='article')`` that becomes:
This is useful if you want to :ref:`use more than one formset in a view
<multiple-formsets-in-view>`.
+.. _formset-rendering:
+
Using a formset in views and templates
======================================
+Formsets have five attributes and five methods associated with rendering.
+
+.. attribute:: BaseFormSet.renderer
+
+ .. versionadded:: 4.0
+
+ Specifies the :doc:`renderer </ref/forms/renderers>` to use for the
+ formset. Defaults to the renderer specified by the :setting:`FORM_RENDERER`
+ setting.
+
+.. attribute:: BaseFormSet.template_name
+
+ .. versionadded:: 4.0
+
+ The name of the template used when calling ``__str__`` or :meth:`.render`.
+ This template renders the formsets management forms and then each form in
+ the formset as per the template defined by the
+ forms :attr:`~django.forms.Form.template_name`. This is a proxy of
+ ``as_table`` by default.
+
+.. attribute:: BaseFormSet.template_name_p
+
+ .. versionadded:: 4.0
+
+ The name of the template used when calling :meth:`.as_p`. By default this
+ is ``'django/forms/formsets/p.html'``. This template renders the formsets
+ management forms and then each form in the formset as per the forms
+ :meth:`~django.forms.Form.as_p` method.
+
+.. attribute:: BaseFormSet.template_name_table
+
+ .. versionadded:: 4.0
+
+ The name of the template used when calling :meth:`.as_table`. By default
+ this is ``'django/forms/formsets/table.html'``. This template renders the
+ formsets management forms and then each form in the formset as per the
+ forms :meth:`~django.forms.Form.as_table` method.
+
+.. attribute:: BaseFormSet.template_name_ul
+
+ .. versionadded:: 4.0
+
+ The name of the template used when calling :meth:`.as_ul`. By default this
+ is ``'django/forms/formsets/ul.html'``. This template renders the formsets
+ management forms and then each form in the formset as per the forms
+ :meth:`~django.forms.Form.as_ul` method.
+
+.. method:: BaseFormSet.get_context()
+
+ .. versionadded:: 4.0
+
+ Returns the context for rendering a formset in a template.
+
+ The available context is:
+
+ * ``formset`` : The instance of the formset.
+
+.. method:: BaseFormSet.render(template_name=None, context=None, renderer=None)
+
+ .. versionadded:: 4.0
+
+ The render method is called by ``__str__`` as well as the :meth:`.as_p`,
+ :meth:`.as_ul`, and :meth:`.as_table` methods. All arguments are optional
+ and will default to:
+
+ * ``template_name``: :attr:`.template_name`
+ * ``context``: Value returned by :meth:`.get_context`
+ * ``renderer``: Value returned by :attr:`.renderer`
+
+.. method:: BaseFormSet.as_p()
+
+ Renders the formset with the :attr:`.template_name_p` template.
+
+.. method:: BaseFormSet.as_table()
+
+ Renders the formset with the :attr:`.template_name_table` template.
+
+.. method:: BaseFormSet.as_ul()
+
+ Renders the formset with the :attr:`.template_name_ul` template.
+
Using a formset inside a view is not very different from using a regular
``Form`` class. The only thing you will want to be aware of is making sure to
use the management form inside the template. Let's look at a sample view::
@@ -821,7 +904,17 @@ deal with the management form:
</table>
</form>
-The above ends up calling the ``as_table`` method on the formset class.
+The above ends up calling the :meth:`BaseFormSet.render` method on the formset
+class. This renders the formset using the template specified by the
+:attr:`~BaseFormSet.template_name` attribute. Similar to forms, by default the
+formset will be rendered ``as_table``, with other helper methods of ``as_p``
+and ``as_ul`` being available. The rendering of the formset can be customized
+by specifying the ``template_name`` attribute, or more generally by
+:ref:`overriding the default template <overriding-built-in-formset-templates>`.
+
+.. versionchanged:: 4.0
+
+ Rendering of formsets was moved to the template engine.
.. _manually-rendered-can-delete-and-can-order:
diff --git a/docs/topics/forms/index.txt b/docs/topics/forms/index.txt
index eed18a2cee..8ed99d5773 100644
--- a/docs/topics/forms/index.txt
+++ b/docs/topics/forms/index.txt
@@ -733,12 +733,17 @@ Reusable form templates
If your site uses the same rendering logic for forms in multiple places, you
can reduce duplication by saving the form's loop in a standalone template and
-using the :ttag:`include` tag to reuse it in other templates:
+overriding the forms :attr:`~django.forms.Form.template_name` attribute to
+render the form using the custom template. The below example will result in
+``{{ form }}`` being rendered as the output of the ``form_snippet.html``
+template.
+
+In your templates:
.. code-block:: html+django
- # In your form template:
- {% include "form_snippet.html" %}
+ # In your template:
+ {{ form }}
# In form_snippet.html:
{% for field in form %}
@@ -748,16 +753,15 @@ using the :ttag:`include` tag to reuse it in other templates:
</div>
{% endfor %}
-If the form object passed to a template has a different name within the
-context, you can alias it using the ``with`` argument of the :ttag:`include`
-tag:
+In your form::
-.. code-block:: html+django
+ class MyForm(forms.Form):
+ template_name = 'form_snippet.html'
+ ...
- {% include "form_snippet.html" with form=comment_form %}
+.. versionchanged:: 4.0
-If you find yourself doing this often, you might consider creating a custom
-:ref:`inclusion tag<howto-custom-template-tags-inclusion-tags>`.
+ Template rendering of forms was added.
Further topics
==============