Django2.0手册:The form rendering API



New in Django 1.11:

In older versions, widgets are rendered using Python. All APIs described
in this document are new.

Django’s form widgets are rendered using Django’s template engines
system
.

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 applications
    typically shouldn’t override built-in templates because they might conflict
    with 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 the
Form.default_renderer attribute or by using the renderer argument
of Widget.render().

Use one of the built-in template form renderers or implement your own. Custom renderers
must implement a render(template_name, context, request=None) method. It
should return a rendered templates (as a string) or raise
TemplateDoesNotExist.

Built-in-template form renderers¶

DjangoTemplates¶

class DjangoTemplates[source]

This renderer uses a standalone
DjangoTemplates
engine (unconnected to what you might have configured in the
TEMPLATES setting). It loads templates first from the built-in form
templates directory in django/forms/templates and then from the installed
apps’ templates directories using the app_directories loader.

If you want to render templates with customizations from your
TEMPLATES setting, such as context processors for example, use the
TemplatesSetting renderer.

Jinja2¶

class Jinja2[source]

This renderer is the same as the DjangoTemplates renderer except that
it uses a Jinja2 backend. Templates
for the built-in widgets are located in django/forms/jinja2 and installed
apps can provide templates in a jinja2 directory.

To use this backend, all the 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[source]

This renderer gives you complete control of how widget templates are sourced.
It uses get_template() to find widget
templates 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 engine
    with APP_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 project
needs can be located.

Context available in widget templates¶

Widget templates receive a context from Widget.get_context(). By
default, widgets receive a single value in the context, widget. This is a
dictionary that contains values like:

  • name
  • value
  • attrs
  • is_hidden
  • template_name

Some widgets add further information to the context. For instance, all widgets
that subclass Input defines widget['type'] and MultiWidget
defines widget['subwidgets'] for looping purposes.

Overriding built-in widget templates¶

Each widget has a template_name attribute with a value such as
input.html. Built-in widget templates are stored in the
django/forms/widgets path. You can provide a custom template for
input.html by defining django/forms/widgets/input.html, for example.
See Built-in widgets for the name of each widget’s template.

If you use the TemplatesSetting renderer, overriding widget templates
works the same as overriding any other template in your project. You can’t
override built-in widget templates using the other built-in renderers.