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_RENDERER
setting. 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 standalone
DjangoTemplates
engine (unconnected to what you might have configured in theTEMPLATES
setting). It loads templates first from the built-in formtemplates directory indjango/forms/templates
and then from the installedapps' templates directories using theapp_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 aJinja2
backend. Templatesfor the built-in widgets are located indjango/forms/jinja2
and installedapps can provide templates in ajinja2
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 theTEMPLATES
setting.
Using this renderer along with the built-in widget templates requires either:
'django.forms'
inINSTALLED_APPS
and at least one enginewithAPP_DIRS=True
.Adding the built-in widgets templates directory in
DIRS
of one of your template engines. To generate that path:
- import django
- 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 subclassInput
defineswidget['type']
andMultiWidget
defineswidget['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 TemplatesSetting
renderer. Then overriding widget templates works the same as overriding any other template in your project.