File: renderers.txt

package info (click to toggle)
python-django 3%3A5.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 61,236 kB
  • sloc: python: 361,585; javascript: 19,250; xml: 211; makefile: 182; sh: 28
file content (254 lines) | stat: -rw-r--r-- 8,742 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
======================
The form rendering API
======================

.. module:: django.forms.renderers
   :synopsis: Built-in form renderers.

Django's form widgets are rendered using Django's :doc:`template engines
system </topics/templates>`.

The form rendering process can be customized at several levels:

* Widgets can specify custom template names.
* Forms and widgets can specify custom renderer classes.
* A widget's template can be overridden by a project. (Reusable applications
  typically shouldn't override built-in templates because they might conflict
  with a project's custom templates.)

.. _low-level-widget-render-api:

The low-level render API
========================

The rendering of form templates is controlled by a customizable renderer class.
A custom renderer can be specified by updating the :setting:`FORM_RENDERER`
setting. It defaults to
``'``:class:`django.forms.renderers.DjangoTemplates`\ ``'``.

By specifying a custom form renderer and overriding
:attr:`~.BaseRenderer.form_template_name` you can adjust the default form
markup across your project from a single place.

You can also provide a custom renderer per-form or per-widget by setting the
:attr:`.Form.default_renderer` attribute or by using the ``renderer`` argument
of :meth:`.Form.render`, or :meth:`.Widget.render`.

Matching points apply to formset rendering. See :ref:`formset-rendering` for
discussion.

Use one of the :ref:`built-in template form renderers
<built-in-template-form-renderers>` or implement your own. Custom renderers
must implement a ``render(template_name, context, request=None)`` method. It
should return a rendered template (as a string) or raise
:exc:`~django.template.TemplateDoesNotExist`.

.. class:: BaseRenderer

    The base class for the built-in form renderers.

    .. attribute:: form_template_name

        The default name of the template to use to render a form.

        Defaults to ``"django/forms/div.html"`` template.

    .. attribute:: formset_template_name

        The default name of the template to use to render a formset.

        Defaults to ``"django/forms/formsets/div.html"`` template.

    .. attribute:: field_template_name

        The default name of the template used to render a ``BoundField``.

        Defaults to ``"django/forms/field.html"``

    .. attribute:: bound_field_class

        .. versionadded:: 5.2

        The default class used to represent form fields across the project.

        Defaults to :class:`.BoundField` class.

        This can be customized further using :attr:`.Form.bound_field_class`
        for per-form overrides, or :attr:`.Field.bound_field_class` for
        per-field overrides.

    .. method:: get_template(template_name)

        Subclasses must implement this method with the appropriate template
        finding logic.

    .. method:: render(template_name, context, request=None)

        Renders the given template, or raises
        :exc:`~django.template.TemplateDoesNotExist`.

.. _built-in-template-form-renderers:

Built-in-template form renderers
================================

``DjangoTemplates``
-------------------

.. class:: DjangoTemplates

This renderer uses a standalone
:class:`~django.template.backends.django.DjangoTemplates`
engine (unconnected to what you might have configured in the
:setting:`TEMPLATES` setting). It loads templates first from the built-in form
templates directory in :source:`django/forms/templates` and then from the
installed apps' templates directories using the :class:`app_directories
<django.template.loaders.app_directories.Loader>` loader.

If you want to render templates with customizations from your
:setting:`TEMPLATES` setting, such as context processors for example, use the
:class:`TemplatesSetting` renderer.

.. class:: DjangoDivFormRenderer

.. deprecated:: 5.0

The alias of :class:`DjangoTemplates`.

``Jinja2``
----------

.. class:: Jinja2

This renderer is the same as the :class:`DjangoTemplates` renderer except that
it uses a :class:`~django.template.backends.jinja2.Jinja2` backend. Templates
for the built-in widgets are located in :source:`django/forms/jinja2` and
installed apps can provide templates in a ``jinja2`` directory.

To use this backend, all the forms and widgets in your project and its
third-party apps must have Jinja2 templates. Unless you provide your own Jinja2
templates for widgets that don't have any, you can't use this renderer. For
example, :mod:`django.contrib.admin` doesn't include Jinja2 templates for its
widgets due to their usage of Django template tags.

.. class:: Jinja2DivFormRenderer

.. deprecated:: 5.0

The alias of :class:`Jinja2`.

``TemplatesSetting``
--------------------

.. class:: TemplatesSetting

This renderer gives you complete control of how form and widget templates are
sourced. It uses :func:`~django.template.loader.get_template` to find templates
based on what's configured in the :setting:`TEMPLATES` setting.

Using this renderer along with the built-in templates requires either:

* ``'django.forms'`` in :setting:`INSTALLED_APPS` and at least one engine
  with :setting:`APP_DIRS=True <TEMPLATES-APP_DIRS>`.

* Adding the built-in templates directory in :setting:`DIRS <TEMPLATES-DIRS>`
  of one of your template engines. To generate that path::

    import django

    django.__path__[0] + "/forms/templates"  # or '/forms/jinja2'

Using this renderer requires you to make sure the form templates your project
needs can be located.

Context available in formset templates
======================================

Formset templates receive a context from :meth:`.BaseFormSet.get_context`. By
default, formsets receive a dictionary with the following values:

* ``formset``: The formset instance.

Context available in form templates
===================================

Form templates receive a context from :meth:`.Form.get_context`. By default,
forms receive a dictionary with the following values:

* ``form``: The bound form.
* ``fields``: All bound fields, except the hidden fields.
* ``hidden_fields``: All hidden bound fields.
* ``errors``: All non field related or hidden field related form errors.

Context available in field templates
====================================

Field templates receive a context from :meth:`.BoundField.get_context`. By
default, fields receive a dictionary with the following values:

* ``field``: The :class:`~django.forms.BoundField`.

Context available in widget templates
=====================================

Widget templates receive a context from :meth:`.Widget.get_context`. By
default, widgets receive a single value in the context, ``widget``. This is a
dictionary that contains values like:

* ``name``
* ``value``
* ``attrs``
* ``is_hidden``
* ``template_name``

Some widgets add further information to the context. For instance, all widgets
that subclass ``Input`` defines ``widget['type']`` and :class:`.MultiWidget`
defines ``widget['subwidgets']`` for looping purposes.

.. _overriding-built-in-formset-templates:

Overriding built-in formset templates
=====================================

:attr:`.BaseFormSet.template_name`

To override formset templates, you must use the :class:`TemplatesSetting`
renderer. Then overriding formset templates works :doc:`the same as
</howto/overriding-templates>` overriding any other template in your project.

.. _overriding-built-in-form-templates:

Overriding built-in form templates
==================================

:attr:`.Form.template_name`

To override form templates, you must use the :class:`TemplatesSetting`
renderer. Then overriding form templates works :doc:`the same as
</howto/overriding-templates>` overriding any other template in your project.

.. _overriding-built-in-field-templates:

Overriding built-in field templates
===================================

:attr:`.Field.template_name`

To override field templates, you must use the :class:`TemplatesSetting`
renderer. Then overriding field templates works :doc:`the same as
</howto/overriding-templates>` overriding any other template in your project.

.. _overriding-built-in-widget-templates:

Overriding built-in widget templates
====================================

Each widget has a ``template_name`` attribute with a value such as
``input.html``. Built-in widget templates are stored in the
``django/forms/widgets`` path. You can provide a custom template for
``input.html`` by defining ``django/forms/widgets/input.html``, for example.
See :ref:`built-in widgets` for the name of each widget's template.

To override widget templates, you must use the :class:`TemplatesSetting`
renderer. Then overriding widget templates works :doc:`the same as
</howto/overriding-templates>` overriding any other template in your project.