mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			241 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ======================
 | |
| 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 template (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"``
 | |
| 
 | |
|     .. attribute:: bound_field_class
 | |
| 
 | |
|         The default class used to represent form fields across the project.
 | |
| 
 | |
|         Defaults to :class:`.BoundField` class.
 | |
| 
 | |
|         This can be customized further using :attr:`.Form.bound_field_class`
 | |
|         for per-form overrides, or :attr:`.Field.bound_field_class` for
 | |
|         per-field overrides.
 | |
| 
 | |
|     .. 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.
 | |
| 
 | |
| ``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.
 | |
| 
 | |
| ``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.
 |