Django 的表单部件是使用 Django 的 模板引擎系统 渲染的。
表单渲染过程可以在几个层次上进行定制:
- 部件可以指定自定义模板名称。
- 表单和部件可以指定自定义渲染器类。
- 组件的模板可以被项目覆盖。(可重用的应用程序通常不应该覆盖内置模板,因为它们可能与项目的自定义模板相冲突。)
低级渲染 API
表单模板的渲染是由一个可定制的渲染器类控制的。可以通过更新 FORM_RENDERER
配置来指定自定义渲染器。它的默认值是 '
django.forms.renderers.DjangoTemplates
'
。
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
Form.default_renderer
attribute or by using the renderer
argument
of Form.render()
, or Widget.render()
.
Matching points apply to formset rendering. See 在视图和模板中使用formset for discussion.
使用 内置模板表单渲染器 或实现你自己的模板表单渲染器。自定义渲染器必须实现一个 render(template_name, context, request=None)
方法。它应该返回一个已渲染的模板(作为一个字符串)或引发 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"
.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"
.4.1 版后已移除.
The
"django/forms/formset/default.html"
template is deprecated and will be removed in Django 5.0. The default will become"django/forms/formset/div.html"
template.
-
get_template
(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
TemplateDoesNotExist
.
-
内置模板表单渲染器
DjangoTemplates
这个渲染器使用一个独立的 DjangoTemplates
引擎(与你在 TEMPLATES
配置中设置的内容无关)。它首先从 django/forms/templates
内置的表单模板目录中加载模板,然后使用 app_directories
加载器从已安装的应用的模板目录中加载模板。
如果你想用你的 TEMPLATES
配置中的自定义配置来渲染模板,例如上下文处理器,使用 TemplatesSetting
渲染器。
Subclass of DjangoTemplates
that specifies
form_template_name
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 FORM_RENDERER
setting:
FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
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.
Jinja2
这个渲染器和 DjangoTemplates
渲染器一样,只是它使用了 Jinja2
后台。内置部件的模板位于 django/forms/jinja2
,安装的应用可以在 jinja2
目录下提供模板。
要使用这个后端,你的项目及其第三方应用程序中的所有表单和部件必须有 Jinja2 模板。除非你为那些没有 Jinja2 模板的部件提供自己的 Jinja2 模板,否则你不能使用这个渲染器。例如, django.contrib.admin
由于使用了 Django 模板标签,所以它的部件不包含 Jinja2 模板。
A transitional renderer as per DjangoDivFormRenderer
above, but
subclassing Jinja2
for use with the Jinja2 backend.
Apply this via the FORM_RENDERER
setting:
FORM_RENDERER = "django.forms.renderers.Jinja2DivFormRenderer"
TemplatesSetting
这个渲染器让你完全控制表单和小工具模板的来源。它使用 get_template()
来查找基于 TEMPLATES
配置中所设置的模板。
使用该渲染器和内置模板需要以下两种方法之一:
'django.forms'
在INSTALLED_APPS
和至少一个引擎有APP_DIRS=True
。在你的一个模板引擎的
DIRS
中添加内置模板目录。要生成该路径:import django django.__path__[0] + '/forms/templates' # or '/forms/jinja2'
使用这个渲染器需要你确保你的项目所需的表单模板可以被找到。
表单集模板中可用的上下文
表单集模板从 BaseFormSet.get_context()
接收一个上下文。默认情况下,表单集接收一个具有以下值的字典:
formset
:表单集实例。
表单模板中可用的上下文
表单模板从 Form.get_context()
接收一个上下文。默认情况下,表单接收一个具有以下值的字典:
form
: 绑定表单fields
: 所有绑定字段,除了隐藏字段。- ·hidden_fields`: 所有隐藏的绑定字段。
errors
: 所有与字段无关的或与隐藏字段有关的表单错误。
部件模板中可用的上下文
部件模板从 Widget.get_context()
中接收一个上下文。默认情况下,部件在上下文中只接收一个值,widget
。这是一个字典,其中包含的值如:
name
value
attrs
is_hidden
template_name
有些部件会给上下文添加更多信息。例如,所有子类 Input
定义了 widget['type']
和 MultiWidget
定义了 widget['subwidgets']
用于循环。
覆盖内置部件模板
每个部件都有一个 template_name
属性,其值如 input.html
。内建的部件模板存储在 django/forms/widgets
路径中,你可以为 input.html
提供一个自定义模板。你可以通过定义 django/forms/widgets/input.html
来为 input.html
提供一个自定义模板,例如。参见 内置部件 了解每个部件的模板名称。
要覆盖部件模板,你必须使用 TemplatesSetting
渲染器。然后覆盖部件模板的工作原理 和覆盖项目中的任何其他模板一样。
讨论区