表单渲染 API

Django 的表单部件是使用 Django 的 模板引擎系统 渲染的。

表单渲染过程可以在几个层次上进行定制:

  • 部件可以指定自定义模板名称。
  • 表单和部件可以指定自定义渲染器类。
  • 组件的模板可以被项目覆盖。(可重用的应用程序通常不应该覆盖内置模板,因为它们可能与项目的自定义模板相冲突。)

低级渲染 API

表单模板的渲染是由一个可定制的渲染器类控制的。可以通过更新 FORM_RENDERER 配置来指定自定义渲染器。它的默认值是 'django.forms.renderers.DjangoTemplates'

通过指定自定义的表单渲染器并覆盖 form_template_name,你可以从一个地方调整整个项目中的默认表单标记。

你还可以通过设置 Form.default_renderer 属性,或者使用 Form.render()Widget.render()renderer 参数,为每个表单或小部件提供自定义渲染器。

相同的要点也适用于表单集的渲染。有关详细信息,请参阅 在视图和模板中使用formset

使用 内置模板表单渲染器 或实现你自己的模板表单渲染器。自定义渲染器必须实现一个 render(template_name, context, request=None) 方法。它应该返回一个已渲染的模板(作为一个字符串)或引发 TemplateDoesNotExist

class BaseRenderer

用于内置表单渲染器的基类。

form_template_name
New in Django 4.1.

用于渲染表单的默认模板名称。

默认为``"django/forms/default.html",是"django/forms/table.html"``的代理。

4.1 版后已移除.

"django/forms/default.html" 模板已被弃用,并将在 Django 5.0 中移除。在那个时候,默认值将变为 "django/forms/div.html"

formset_template_name
New in Django 4.1.

用于渲染表单集的默认模板名称。

默认值为 "django/forms/formsets/default.html",它是 "django/forms/formsets/table.html" 的代理。

4.1 版后已移除.

"django/forms/formset/default.html" 模板已被弃用,并将在 Django 5.0 中移除。在那个时候,默认值将变为 "django/forms/formset/div.html" 模板。

get_template(template_name)

子类必须使用适当的模板查找逻辑来实现此方法。

render(template_name, context, request=None)

渲染给定的模板,或引发 TemplateDoesNotExist

内置模板表单渲染器

DjangoTemplates

class DjangoTemplates

这个渲染器使用一个独立的 DjangoTemplates 引擎(与你在 TEMPLATES 设置中配置的可能不同)。它首先从 django/forms/templates 中的内置表单模板目录加载模板,然后使用 app_directories 加载程序从已安装的应用程序模板目录加载模板。

如果你想用你的 TEMPLATES 配置中的自定义配置来渲染模板,例如上下文处理器,使用 TemplatesSetting 渲染器。

class DjangoDivFormRenderer
New in Django 4.1.

DjangoTemplates 的子类,将 form_template_nameformset_template_name 分别指定为 "django/forms/div.html""django/forms/formset/div.html"

这是一个过渡性的渲染器,用于选择使用新的基于 <div> 的模板,这是从 Django 5.0 开始的默认选项。

通过 FORM_RENDERER 设置来应用这个渲染器:

FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"

一旦 <div> 模板成为默认选项,这个过渡性渲染器将被弃用,并在 Django 6.0 中删除。此时可以移除 FORM_RENDERER 声明。

Jinja2

class Jinja2

这个渲染器与 DjangoTemplates 渲染器相同,唯一的区别是它使用了 Jinja2 后端。内置小部件的模板位于 django/forms/jinja2 中,已安装的应用程序可以在 jinja2 目录中提供模板。

要使用这个后端,你的项目及其第三方应用程序中的所有表单和部件必须有 Jinja2 模板。除非你为那些没有 Jinja2 模板的部件提供自己的 Jinja2 模板,否则你不能使用这个渲染器。例如, django.contrib.admin 由于使用了 Django 模板标签,所以它的部件不包含 Jinja2 模板。

class Jinja2DivFormRenderer
New in Django 4.1.

与上面的 DjangoDivFormRenderer 一样,这是一个过渡性渲染器,但是它是使用 Jinja2 后端的。

通过 FORM_RENDERER 设置来应用这个渲染器:

FORM_RENDERER = "django.forms.renderers.Jinja2DivFormRenderer"

TemplatesSetting

class 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'] 用于循环。

覆盖内置的表单集模板

BaseFormSet.template_name

要重写表单集模板,你必须使用 TemplatesSetting 渲染器。然后,重写表单集模板的工作方式与重写项目中的任何其他模板 相同

覆盖内置表单模板

Form.template_name

要重写表单模板,你必须使用 TemplatesSetting 渲染器。然后,重写表单模板的工作方式与重写项目中的任何其他模板 相同

覆盖内置部件模板

每个部件都有一个 template_name 属性,其值如 input.html。内建的部件模板存储在 django/forms/widgets 路径中,你可以为 input.html 提供一个自定义模板。你可以通过定义 django/forms/widgets/input.html 来为 input.html 提供一个自定义模板,例如。参见 内置部件 了解每个部件的模板名称。

要覆盖部件模板,你必须使用 TemplatesSetting 渲染器。然后覆盖部件模板的工作原理 和覆盖项目中的任何其他模板一样

Back to Top