======================The form rendering API======================.. module:: django.forms.renderers:synopsis: Built-in form renderers.Django's form widgets are rendered using Django's :doc:`template enginessystem </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 applicationstypically shouldn't override built-in templates because they might conflictwith 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 formmarkup 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`` argumentof :meth:`.Form.render`, or :meth:`.Widget.render`.Matching points apply to formset rendering. See :ref:`formset-rendering` fordiscussion.Use one of the :ref:`built-in template form renderers<built-in-template-form-renderers>` or implement your own. Custom renderersmust implement a ``render(template_name, context, request=None)`` method. Itshould return a rendered templates (as a string) or raise:exc:`~django.template.TemplateDoesNotExist`... class:: BaseRendererThe base class for the built-in form renderers... attribute:: form_template_name.. versionadded:: 4.1The 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"``... deprecated:: 4.1The ``"django/forms/default.html"`` template is deprecated and will beremoved in Django 5.0. The default will become``"django/forms/div.html"`` at that time... attribute:: formset_template_name.. versionadded:: 4.1The default name of the template to use to render a formset.Defaults to ``"django/forms/formsets/default.html"``, which is a proxyfor ``"django/forms/formsets/table.html"``... deprecated:: 4.1The ``"django/forms/formset/default.html"`` template is deprecated andwill be removed in Django 5.0. The default will become``"django/forms/formset/div.html"`` template... method:: get_template(template_name)Subclasses must implement this method with the appropriate templatefinding 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:: DjangoTemplatesThis 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 formtemplates directory in ``django/forms/templates`` and then from the installedapps' 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.. versionadded:: 4.1Subclass 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>`` basedtemplates, 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 willbe deprecated, for removal in Django 6.0. The ``FORM_RENDERER`` declaration canbe removed at that time.``Jinja2``----------.. class:: Jinja2This renderer is the same as the :class:`DjangoTemplates` renderer except thatit uses a :class:`~django.template.backends.jinja2.Jinja2` backend. Templatesfor the built-in widgets are located in ``django/forms/jinja2`` and installedapps can provide templates in a ``jinja2`` directory.To use this backend, all the forms and widgets in your project and itsthird-party apps must have Jinja2 templates. Unless you provide your own Jinja2templates for widgets that don't have any, you can't use this renderer. Forexample, :mod:`django.contrib.admin` doesn't include Jinja2 templates for itswidgets due to their usage of Django template tags... class:: Jinja2DivFormRenderer.. versionadded:: 4.1A transitional renderer as per :class:`DjangoDivFormRenderer` above, butsubclassing :class:`Jinja2` for use with the Jinja2 backend.Apply this via the :setting:`FORM_RENDERER` setting::FORM_RENDERER = "django.forms.renderers.Jinja2DivFormRenderer"``TemplatesSetting``--------------------.. class:: TemplatesSettingThis renderer gives you complete control of how form and widget templates aresourced. It uses :func:`~django.template.loader.get_template` to find templatesbased 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 enginewith :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 djangodjango.__path__[0] + '/forms/templates' # or '/forms/jinja2'Using this renderer requires you to make sure the form templates your projectneeds can be located.Context available in formset templates======================================.. versionadded:: 4.0Formset templates receive a context from :meth:`.BaseFormSet.get_context`. Bydefault, formsets receive a dictionary with the following values:* ``formset``: The formset instance.Context available in form templates===================================.. versionadded:: 4.0Form 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 widget templates=====================================Widget templates receive a context from :meth:`.Widget.get_context`. Bydefault, widgets receive a single value in the context, ``widget``. This is adictionary that contains values like:* ``name``* ``value``* ``attrs``* ``is_hidden``* ``template_name``Some widgets add further information to the context. For instance, all widgetsthat subclass ``Input`` defines ``widget['type']`` and :class:`.MultiWidget`defines ``widget['subwidgets']`` for looping purposes... _overriding-built-in-formset-templates:Overriding built-in formset templates=====================================.. versionadded:: 4.0: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==================================.. versionadded:: 4.0: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... _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.