renderers.txt 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. ======================
  2. The form rendering API
  3. ======================
  4. .. module:: django.forms.renderers
  5. :synopsis: Built-in form renderers.
  6. Django's form widgets are rendered using Django's :doc:`template engines
  7. system </topics/templates>`.
  8. The form rendering process can be customized at several levels:
  9. * Widgets can specify custom template names.
  10. * Forms and widgets can specify custom renderer classes.
  11. * A widget's template can be overridden by a project. (Reusable applications
  12. typically shouldn't override built-in templates because they might conflict
  13. with a project's custom templates.)
  14. .. _low-level-widget-render-api:
  15. The low-level render API
  16. ========================
  17. The rendering of form templates is controlled by a customizable renderer class.
  18. A custom renderer can be specified by updating the :setting:`FORM_RENDERER`
  19. setting. It defaults to
  20. ``'``:class:`django.forms.renderers.DjangoTemplates`\ ``'``.
  21. By specifying a custom form renderer and overriding
  22. :attr:`~.BaseRenderer.form_template_name` you can adjust the default form
  23. markup across your project from a single place.
  24. You can also provide a custom renderer per-form or per-widget by setting the
  25. :attr:`.Form.default_renderer` attribute or by using the ``renderer`` argument
  26. of :meth:`.Form.render`, or :meth:`.Widget.render`.
  27. Matching points apply to formset rendering. See :ref:`formset-rendering` for
  28. discussion.
  29. Use one of the :ref:`built-in template form renderers
  30. <built-in-template-form-renderers>` or implement your own. Custom renderers
  31. must implement a ``render(template_name, context, request=None)`` method. It
  32. should return a rendered templates (as a string) or raise
  33. :exc:`~django.template.TemplateDoesNotExist`.
  34. .. class:: BaseRenderer
  35. The base class for the built-in form renderers.
  36. .. attribute:: form_template_name
  37. .. versionadded:: 4.1
  38. The default name of the template to use to render a form.
  39. Defaults to ``"django/forms/default.html"``, which is a proxy for
  40. ``"django/forms/table.html"``.
  41. .. deprecated:: 4.1
  42. The ``"django/forms/default.html"`` template is deprecated and will be
  43. removed in Django 5.0. The default will become
  44. ``"django/forms/div.html"`` at that time.
  45. .. attribute:: formset_template_name
  46. .. versionadded:: 4.1
  47. The default name of the template to use to render a formset.
  48. Defaults to ``"django/forms/formsets/default.html"``, which is a proxy
  49. for ``"django/forms/formsets/table.html"``.
  50. .. deprecated:: 4.1
  51. The ``"django/forms/formset/default.html"`` template is deprecated and
  52. will be removed in Django 5.0. The default will become
  53. ``"django/forms/formset/div.html"`` template.
  54. .. method:: get_template(template_name)
  55. Subclasses must implement this method with the appropriate template
  56. finding logic.
  57. .. method:: render(template_name, context, request=None)
  58. Renders the given template, or raises
  59. :exc:`~django.template.TemplateDoesNotExist`.
  60. .. _built-in-template-form-renderers:
  61. Built-in-template form renderers
  62. ================================
  63. ``DjangoTemplates``
  64. -------------------
  65. .. class:: DjangoTemplates
  66. This renderer uses a standalone
  67. :class:`~django.template.backends.django.DjangoTemplates`
  68. engine (unconnected to what you might have configured in the
  69. :setting:`TEMPLATES` setting). It loads templates first from the built-in form
  70. templates directory in ``django/forms/templates`` and then from the installed
  71. apps' templates directories using the :class:`app_directories
  72. <django.template.loaders.app_directories.Loader>` loader.
  73. If you want to render templates with customizations from your
  74. :setting:`TEMPLATES` setting, such as context processors for example, use the
  75. :class:`TemplatesSetting` renderer.
  76. .. class:: DjangoDivFormRenderer
  77. .. versionadded:: 4.1
  78. Subclass of :class:`DjangoTemplates` that specifies
  79. :attr:`~BaseRenderer.form_template_name` and
  80. :attr:`~BaseRenderer.formset_template_name` as ``"django/forms/div.html"`` and
  81. ``"django/forms/formset/div.html"`` respectively.
  82. This is a transitional renderer for opt-in to the new ``<div>`` based
  83. templates, which are the default from Django 5.0.
  84. Apply this via the :setting:`FORM_RENDERER` setting::
  85. FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
  86. Once the ``<div>`` templates are the default, this transitional renderer will
  87. be deprecated, for removal in Django 6.0. The ``FORM_RENDERER`` declaration can
  88. be removed at that time.
  89. ``Jinja2``
  90. ----------
  91. .. class:: Jinja2
  92. This renderer is the same as the :class:`DjangoTemplates` renderer except that
  93. it uses a :class:`~django.template.backends.jinja2.Jinja2` backend. Templates
  94. for the built-in widgets are located in ``django/forms/jinja2`` and installed
  95. apps can provide templates in a ``jinja2`` directory.
  96. To use this backend, all the forms and widgets in your project and its
  97. third-party apps must have Jinja2 templates. Unless you provide your own Jinja2
  98. templates for widgets that don't have any, you can't use this renderer. For
  99. example, :mod:`django.contrib.admin` doesn't include Jinja2 templates for its
  100. widgets due to their usage of Django template tags.
  101. .. class:: Jinja2DivFormRenderer
  102. .. versionadded:: 4.1
  103. A transitional renderer as per :class:`DjangoDivFormRenderer` above, but
  104. subclassing :class:`Jinja2` for use with the Jinja2 backend.
  105. Apply this via the :setting:`FORM_RENDERER` setting::
  106. FORM_RENDERER = "django.forms.renderers.Jinja2DivFormRenderer"
  107. ``TemplatesSetting``
  108. --------------------
  109. .. class:: TemplatesSetting
  110. This renderer gives you complete control of how form and widget templates are
  111. sourced. It uses :func:`~django.template.loader.get_template` to find templates
  112. based on what's configured in the :setting:`TEMPLATES` setting.
  113. Using this renderer along with the built-in templates requires either:
  114. * ``'django.forms'`` in :setting:`INSTALLED_APPS` and at least one engine
  115. with :setting:`APP_DIRS=True <TEMPLATES-APP_DIRS>`.
  116. * Adding the built-in templates directory in :setting:`DIRS <TEMPLATES-DIRS>`
  117. of one of your template engines. To generate that path::
  118. import django
  119. django.__path__[0] + '/forms/templates' # or '/forms/jinja2'
  120. Using this renderer requires you to make sure the form templates your project
  121. needs can be located.
  122. Context available in formset templates
  123. ======================================
  124. Formset templates receive a context from :meth:`.BaseFormSet.get_context`. By
  125. default, formsets receive a dictionary with the following values:
  126. * ``formset``: The formset instance.
  127. Context available in form templates
  128. ===================================
  129. Form templates receive a context from :meth:`.Form.get_context`. By default,
  130. forms receive a dictionary with the following values:
  131. * ``form``: The bound form.
  132. * ``fields``: All bound fields, except the hidden fields.
  133. * ``hidden_fields``: All hidden bound fields.
  134. * ``errors``: All non field related or hidden field related form errors.
  135. Context available in widget templates
  136. =====================================
  137. Widget templates receive a context from :meth:`.Widget.get_context`. By
  138. default, widgets receive a single value in the context, ``widget``. This is a
  139. dictionary that contains values like:
  140. * ``name``
  141. * ``value``
  142. * ``attrs``
  143. * ``is_hidden``
  144. * ``template_name``
  145. Some widgets add further information to the context. For instance, all widgets
  146. that subclass ``Input`` defines ``widget['type']`` and :class:`.MultiWidget`
  147. defines ``widget['subwidgets']`` for looping purposes.
  148. .. _overriding-built-in-formset-templates:
  149. Overriding built-in formset templates
  150. =====================================
  151. :attr:`.BaseFormSet.template_name`
  152. To override formset templates, you must use the :class:`TemplatesSetting`
  153. renderer. Then overriding widget templates works :doc:`the same as
  154. </howto/overriding-templates>` overriding any other template in your project.
  155. .. _overriding-built-in-form-templates:
  156. Overriding built-in form templates
  157. ==================================
  158. :attr:`.Form.template_name`
  159. To override form templates, you must use the :class:`TemplatesSetting`
  160. renderer. Then overriding widget templates works :doc:`the same as
  161. </howto/overriding-templates>` overriding any other template in your project.
  162. .. _overriding-built-in-widget-templates:
  163. Overriding built-in widget templates
  164. ====================================
  165. Each widget has a ``template_name`` attribute with a value such as
  166. ``input.html``. Built-in widget templates are stored in the
  167. ``django/forms/widgets`` path. You can provide a custom template for
  168. ``input.html`` by defining ``django/forms/widgets/input.html``, for example.
  169. See :ref:`built-in widgets` for the name of each widget's template.
  170. To override widget templates, you must use the :class:`TemplatesSetting`
  171. renderer. Then overriding widget templates works :doc:`the same as
  172. </howto/overriding-templates>` overriding any other template in your project.