表单渲染 API

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

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

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

低级渲染 API

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

你也可以通过设置 Form.default_renderer 属性或使用 Widget.render()renderer 参数来提供一个自定义的渲染器。

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

内置模板表单渲染器

DjangoTemplates

class DjangoTemplates

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

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

Jinja2

class Jinja2

这个渲染器和 DjangoTemplates 渲染器一样,只是它使用了 Jinja2 后台。内置部件的模板位于 django/forms/jinja2,安装的应用可以在 jinja2 目录下提供模板。

To use this backend, all the forms and 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, django.contrib.admin doesn't include Jinja2 templates for its widgets due to their usage of Django template tags.

TemplatesSetting

class TemplatesSetting

这个渲染器可以让你完全控制部件模板的来源。它使用 get_template() 根据 TEMPLATES 配置中设置的内容来查找部件模板。

使用这个渲染器和内置的部件模板有以下两种方式:

  • 'django.forms'INSTALLED_APPS 和至少一个引擎有 APP_DIRS=True

  • 在你的一个模板引擎的 DIRS 中添加内置部件模板目录。要生成该路径:

    import django
    django.__path__[0] + '/forms/templates'  # or '/forms/jinja2'
    

使用这个渲染器需要你确保你的项目所需的表单模板可以被找到。

Context available in formset templates

New in Django 4.0.

Formset templates receive a context from BaseFormSet.get_context(). By default, formsets receive a dictionary with the following values:

  • formset: The formset instance.

Context available in form templates

New in Django 4.0.

Form templates receive a context from Form.get_context(). By default, forms receive a dictionary with the following values:

  • form: The bound form.
  • fields: All bound fields, except the hidden fields.
  • hidden_fields: All hidden bound fields.
  • errors: All non field related or hidden field related form errors.

部件模板中可用的上下文

部件模板从 Widget.get_context() 中接收一个上下文。默认情况下,部件在上下文中只接收一个值,widget。这是一个字典,其中包含的值如:

  • name
  • value
  • attrs
  • is_hidden
  • template_name

有些部件会给上下文添加更多信息。例如,所有子类 Input 定义了 widget['type']MultiWidget 定义了 widget['subwidgets'] 用于循环。

Overriding built-in formset templates

New in Django 4.0.

BaseFormSet.template_name

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

Overriding built-in form templates

New in Django 4.0.

Form.template_name

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

覆盖内置部件模板

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

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