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

    You can also provide a custom renderer by setting the Form.default_renderer attribute or by using the renderer argument of .

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

    class DjangoTemplates

    This renderer uses a standalone DjangoTemplates engine (unconnected to what you might have configured in the 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.

    class Jinja2

    This renderer is the same as the renderer except that it uses a Jinja2 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 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, doesn’t include Jinja2 templates for its widgets due to their usage of Django template tags.

    class TemplatesSetting

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

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

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

    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
    • template_name

    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.

    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 Built-in widgets for the name of each widget’s template.

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