2016-12-27 22:00:56 +00:00
|
|
|
======================
|
|
|
|
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`\ ``'``.
|
|
|
|
|
2022-04-26 14:01:59 +00:00
|
|
|
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
|
2016-12-27 22:00:56 +00:00
|
|
|
:attr:`.Form.default_renderer` attribute or by using the ``renderer`` argument
|
2022-04-26 14:01:59 +00:00
|
|
|
of :meth:`.Form.render`, or :meth:`.Widget.render`.
|
|
|
|
|
|
|
|
Matching points apply to formset rendering. See :ref:`formset-rendering` for
|
|
|
|
discussion.
|
2016-12-27 22:00:56 +00:00
|
|
|
|
|
|
|
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 templates (as a string) or raise
|
|
|
|
:exc:`~django.template.TemplateDoesNotExist`.
|
|
|
|
|
2022-04-21 12:32:52 +00:00
|
|
|
.. class:: BaseRenderer
|
|
|
|
|
|
|
|
The base class for the built-in form renderers.
|
|
|
|
|
2022-04-26 14:01:59 +00:00
|
|
|
.. attribute:: form_template_name
|
|
|
|
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
|
|
|
|
The default name of the template to use to render a form.
|
|
|
|
|
|
|
|
Defaults to ``"django/forms/default.html"``, which is a proxy for
|
|
|
|
``"django/forms/table.html"``.
|
|
|
|
|
2022-05-05 12:26:09 +00:00
|
|
|
.. deprecated:: 4.1
|
|
|
|
|
|
|
|
The ``"django/forms/default.html"`` template is deprecated and will be
|
|
|
|
removed in Django 5.0. The default will become
|
2022-08-06 11:43:16 +00:00
|
|
|
``"django/forms/div.html"`` at that time.
|
2022-05-05 12:26:09 +00:00
|
|
|
|
2022-04-26 14:01:59 +00:00
|
|
|
.. attribute:: formset_template_name
|
|
|
|
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
|
|
|
|
The default name of the template to use to render a formset.
|
|
|
|
|
|
|
|
Defaults to ``"django/forms/formsets/default.html"``, which is a proxy
|
|
|
|
for ``"django/forms/formsets/table.html"``.
|
|
|
|
|
2022-05-05 12:26:09 +00:00
|
|
|
.. deprecated:: 4.1
|
|
|
|
|
|
|
|
The ``"django/forms/formset/default.html"`` template is deprecated and
|
|
|
|
will be removed in Django 5.0. The default will become
|
|
|
|
``"django/forms/formset/div.html"`` template.
|
|
|
|
|
2022-04-21 12:32:52 +00:00
|
|
|
.. 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`.
|
|
|
|
|
2016-12-27 22:00:56 +00:00
|
|
|
.. _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
|
2022-06-30 12:08:49 +00:00
|
|
|
templates directory in :source:`django/forms/templates` and then from the
|
|
|
|
installed apps' templates directories using the :class:`app_directories
|
2016-12-27 22:00:56 +00:00
|
|
|
<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.
|
|
|
|
|
2022-05-05 12:26:09 +00:00
|
|
|
.. class:: DjangoDivFormRenderer
|
|
|
|
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
|
|
|
|
Subclass of :class:`DjangoTemplates` that specifies
|
|
|
|
:attr:`~BaseRenderer.form_template_name` and
|
|
|
|
:attr:`~BaseRenderer.formset_template_name` as ``"django/forms/div.html"`` and
|
|
|
|
``"django/forms/formset/div.html"`` respectively.
|
|
|
|
|
|
|
|
This is a transitional renderer for opt-in to the new ``<div>`` based
|
|
|
|
templates, which are the default from Django 5.0.
|
|
|
|
|
|
|
|
Apply this via the :setting:`FORM_RENDERER` setting::
|
|
|
|
|
|
|
|
FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
|
|
|
|
|
|
|
|
Once the ``<div>`` templates are the default, this transitional renderer will
|
|
|
|
be deprecated, for removal in Django 6.0. The ``FORM_RENDERER`` declaration can
|
|
|
|
be removed at that time.
|
|
|
|
|
2016-12-27 22:00:56 +00:00
|
|
|
``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
|
2022-06-30 12:08:49 +00:00
|
|
|
for the built-in widgets are located in :source:`django/forms/jinja2` and
|
|
|
|
installed apps can provide templates in a ``jinja2`` directory.
|
2016-12-27 22:00:56 +00:00
|
|
|
|
2021-09-10 07:06:01 +00:00
|
|
|
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.
|
2016-12-27 22:00:56 +00:00
|
|
|
|
2022-05-05 12:26:09 +00:00
|
|
|
.. class:: Jinja2DivFormRenderer
|
|
|
|
|
|
|
|
.. versionadded:: 4.1
|
|
|
|
|
|
|
|
A transitional renderer as per :class:`DjangoDivFormRenderer` above, but
|
|
|
|
subclassing :class:`Jinja2` for use with the Jinja2 backend.
|
|
|
|
|
|
|
|
Apply this via the :setting:`FORM_RENDERER` setting::
|
|
|
|
|
|
|
|
FORM_RENDERER = "django.forms.renderers.Jinja2DivFormRenderer"
|
|
|
|
|
2016-12-27 22:00:56 +00:00
|
|
|
``TemplatesSetting``
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
.. class:: TemplatesSetting
|
|
|
|
|
2021-12-21 22:01:21 +00:00
|
|
|
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.
|
2016-12-27 22:00:56 +00:00
|
|
|
|
2021-12-21 22:01:21 +00:00
|
|
|
Using this renderer along with the built-in templates requires either:
|
2016-12-27 22:00:56 +00:00
|
|
|
|
2017-10-20 18:00:51 +00:00
|
|
|
* ``'django.forms'`` in :setting:`INSTALLED_APPS` and at least one engine
|
|
|
|
with :setting:`APP_DIRS=True <TEMPLATES-APP_DIRS>`.
|
2016-12-27 22:00:56 +00:00
|
|
|
|
2021-12-21 22:01:21 +00:00
|
|
|
* Adding the built-in templates directory in :setting:`DIRS <TEMPLATES-DIRS>`
|
|
|
|
of one of your template engines. To generate that path::
|
2017-06-05 21:26:49 +00:00
|
|
|
|
|
|
|
import django
|
2023-03-01 12:35:43 +00:00
|
|
|
|
2017-06-05 21:26:49 +00:00
|
|
|
django.__path__[0] + "/forms/templates" # or '/forms/jinja2'
|
2016-12-27 22:00:56 +00:00
|
|
|
|
|
|
|
Using this renderer requires you to make sure the form templates your project
|
|
|
|
needs can be located.
|
|
|
|
|
2021-09-10 07:06:01 +00:00
|
|
|
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.
|
|
|
|
|
2016-12-27 22:00:56 +00:00
|
|
|
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.
|
|
|
|
|
2021-09-10 07:06:01 +00:00
|
|
|
.. _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 widget 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 widget templates works :doc:`the same as
|
|
|
|
</howto/overriding-templates>` overriding any other template in your project.
|
|
|
|
|
2018-09-11 19:14:53 +00:00
|
|
|
.. _overriding-built-in-widget-templates:
|
|
|
|
|
2016-12-27 22:00:56 +00:00
|
|
|
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.
|
|
|
|
|
2018-09-11 19:14:53 +00:00
|
|
|
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.
|