The form rendering API

    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.)

    The rendering of form templates is controlled by a customizable renderer class. A custom renderer can be specified by updating the FORM_RENDERER setting. It defaults to ''.

    By specifying a custom form renderer and overriding 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 attribute or by using the renderer argument of Form.render(), or .

    Matching points apply to formset rendering. See Using a formset in views and templates for discussion.

    Use one of the 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 TemplateDoesNotExist.

    class BaseRenderer

    The base class for the built-in form renderers.

    • form_template_name

      New in Django 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".

      Deprecated since version 4.1.

      The "django/forms/default.html" template is deprecated and will be removed in Django 5.0. The default will become "django/forms/div.html" at that time.

    • formset_template_name

      New in Django 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".

      Deprecated since version 4.1.

    • (template_name)

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

    • render(template_name, context, request=None)

      Renders the given template, or raises .

    Built-in-template form renderers

    class DjangoTemplates

    This renderer uses a standalone engine (unconnected to what you might have configured in the TEMPLATES setting). It loads templates first from the built-in form templates directory in django/forms/templates and then from the installed apps’ templates directories using the loader.

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

    class DjangoDivFormRenderer

    New in Django 4.1.

    Subclass of DjangoTemplates that specifies and 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:

    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.

    class Jinja2

    This renderer is the same as the DjangoTemplates renderer except that it uses a backend. Templates for the built-in widgets are located in 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, django.contrib.admin doesn’t include Jinja2 templates for its widgets due to their usage of Django template tags.

    class Jinja2DivFormRenderer

    New in Django 4.1.

    A transitional renderer as per above, but subclassing Jinja2 for use with the Jinja2 backend.

    class TemplatesSetting

    This renderer gives you complete control of how form and widget templates are sourced. It uses to find templates based on what’s configured in the TEMPLATES setting.

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

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

    New in Django 4.0.

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

    • formset: The formset instance.

    Context available in form templates

    New in Django 4.0.

    Form templates receive a context from . 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.

    Widget templates receive a context from 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

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

    Overriding built-in formset templates

    New in Django 4.0.

    To override formset templates, you must use the TemplatesSetting renderer. Then overriding widget templates works overriding any other template in your project.

    New in Django 4.0.

    Form.template_name

    To override form templates, you must use the renderer. Then overriding widget templates works the same as overriding any other template in your project.

    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 by defining django/forms/widgets/input.html, for example. See Built-in widgets for the name of each widget’s template.