The form rendering API

Django's form widgets are rendered using Django's template enginessystem.

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

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 FORM_RENDERERsetting. It defaults to'django.forms.renderers.DjangoTemplates'.

You can also provide a custom renderer by setting theForm.default_renderer attribute or by using the renderer argumentof Widget.render().

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

Built-in-template form renderers

DjangoTemplates

  • class DjangoTemplates[源代码]
  • This renderer uses a standaloneDjangoTemplatesengine (unconnected to what you might have configured in theTEMPLATES setting). It loads templates first from the built-in formtemplates directory in django/forms/templates and then from the installedapps' templates directories using the app_directories loader.

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

Jinja2

  • class Jinja2[源代码]
  • This renderer is the same as the DjangoTemplates renderer except thatit uses a 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 widgets in your project and its third-party appsmust have Jinja2 templates. Unless you provide your own Jinja2 templates forwidgets that don't have any, you can't use this renderer. For example,django.contrib.admin doesn't include Jinja2 templates for its widgetsdue to their usage of Django template tags.

TemplatesSetting

  • class TemplatesSetting[源代码]
  • This renderer gives you complete control of how widget templates are sourced.It uses get_template() to find widgettemplates based on what's configured in the TEMPLATES setting.

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

  • 'django.forms' in INSTALLED_APPS and at least one enginewith APP_DIRS=True.

  • Adding the built-in widgets templates directory in DIRS of one of your template engines. To generate that path:

  1. import django
  2. django.__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 widget templates

Widget templates receive a context from 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 MultiWidgetdefines widget['subwidgets'] for looping purposes.

Overriding built-in widget templates

Each widget has a template_name attribute with a value such asinput.html. Built-in widget templates are stored in thedjango/forms/widgets path. You can provide a custom template forinput.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 TemplatesSettingrenderer. Then overriding widget templates works the same as overriding any other template in your project.