123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- ======================
- The form rendering API
- ======================
- .. module:: django.forms.renderers
- :synopsis: Built-in form renderers.
- Django's form widgets are rendered using Django's :doc:`template engines
- system </topics/templates>`.
- 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.)
- .. _low-level-widget-render-api:
- 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 :setting:`FORM_RENDERER`
- setting. It defaults to
- ``'``:class:`django.forms.renderers.DjangoTemplates`\ ``'``.
- By specifying a custom form renderer and overriding
- :attr:`~.BaseRenderer.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
- :attr:`.Form.default_renderer` attribute or by using the ``renderer`` argument
- of :meth:`.Form.render`, or :meth:`.Widget.render`.
- Matching points apply to formset rendering. See :ref:`formset-rendering` for
- discussion.
- Use one of the :ref:`built-in template form renderers
- <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
- :exc:`~django.template.TemplateDoesNotExist`.
- .. class:: BaseRenderer
- The base class for the built-in form renderers.
- .. attribute:: form_template_name
- The default name of the template to use to render a form.
- Defaults to ``"django/forms/div.html"`` template.
- .. attribute:: formset_template_name
- The default name of the template to use to render a formset.
- Defaults to ``"django/forms/formsets/div.html"`` template.
- .. attribute:: field_template_name
- The default name of the template used to render a ``BoundField``.
- Defaults to ``"django/forms/field.html"``
- .. method:: get_template(template_name)
- Subclasses must implement this method with the appropriate template
- finding logic.
- .. method:: render(template_name, context, request=None)
- Renders the given template, or raises
- :exc:`~django.template.TemplateDoesNotExist`.
- .. _built-in-template-form-renderers:
- Built-in-template form renderers
- ================================
- ``DjangoTemplates``
- -------------------
- .. class:: DjangoTemplates
- This renderer uses a standalone
- :class:`~django.template.backends.django.DjangoTemplates`
- engine (unconnected to what you might have configured in the
- :setting:`TEMPLATES` setting). It loads templates first from the built-in form
- templates directory in :source:`django/forms/templates` and then from the
- installed apps' templates directories using the :class:`app_directories
- <django.template.loaders.app_directories.Loader>` loader.
- If you want to render templates with customizations from your
- :setting:`TEMPLATES` setting, such as context processors for example, use the
- :class:`TemplatesSetting` renderer.
- .. class:: DjangoDivFormRenderer
- .. deprecated:: 5.0
- The alias of :class:`DjangoTemplates`.
- ``Jinja2``
- ----------
- .. class:: Jinja2
- This renderer is the same as the :class:`DjangoTemplates` renderer except that
- it uses a :class:`~django.template.backends.jinja2.Jinja2` backend. Templates
- for the built-in widgets are located in :source:`django/forms/jinja2` and
- installed apps can provide templates in a ``jinja2`` directory.
- 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, :mod:`django.contrib.admin` doesn't include Jinja2 templates for its
- widgets due to their usage of Django template tags.
- .. class:: Jinja2DivFormRenderer
- .. deprecated:: 5.0
- The alias of :class:`Jinja2`.
- ``TemplatesSetting``
- --------------------
- .. class:: TemplatesSetting
- This renderer gives you complete control of how form and widget templates are
- sourced. It uses :func:`~django.template.loader.get_template` to find templates
- based on what's configured in the :setting:`TEMPLATES` setting.
- Using this renderer along with the built-in templates requires either:
- * ``'django.forms'`` in :setting:`INSTALLED_APPS` and at least one engine
- with :setting:`APP_DIRS=True <TEMPLATES-APP_DIRS>`.
- * Adding the built-in templates directory in :setting:`DIRS <TEMPLATES-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 formset templates
- ======================================
- Formset templates receive a context from :meth:`.BaseFormSet.get_context`. By
- default, formsets receive a dictionary with the following values:
- * ``formset``: The formset instance.
- Context available in form templates
- ===================================
- Form templates receive a context from :meth:`.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.
- Context available in field templates
- ====================================
- Field templates receive a context from :meth:`.BoundField.get_context`. By
- default, fields receive a dictionary with the following values:
- * ``field``: The :class:`~django.forms.BoundField`.
- Context available in widget templates
- =====================================
- Widget templates receive a context from :meth:`.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 :class:`.MultiWidget`
- defines ``widget['subwidgets']`` for looping purposes.
- .. _overriding-built-in-formset-templates:
- Overriding built-in formset templates
- =====================================
- :attr:`.BaseFormSet.template_name`
- To override formset templates, you must use the :class:`TemplatesSetting`
- renderer. Then overriding formset templates works :doc:`the same as
- </howto/overriding-templates>` overriding any other template in your project.
- .. _overriding-built-in-form-templates:
- Overriding built-in form templates
- ==================================
- :attr:`.Form.template_name`
- To override form templates, you must use the :class:`TemplatesSetting`
- renderer. Then overriding form templates works :doc:`the same as
- </howto/overriding-templates>` overriding any other template in your project.
- .. _overriding-built-in-field-templates:
- Overriding built-in field templates
- ===================================
- :attr:`.Field.template_name`
- To override field templates, you must use the :class:`TemplatesSetting`
- renderer. Then overriding field templates works :doc:`the same as
- </howto/overriding-templates>` overriding any other template in your project.
- .. _overriding-built-in-widget-templates:
- 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 :ref:`built-in widgets` for the name of each widget's template.
- To override widget templates, you must use the :class:`TemplatesSetting`
- renderer. Then overriding widget templates works :doc:`the same as
- </howto/overriding-templates>` overriding any other template in your project.
|