1. ===================================================
    
  2. ``TemplateResponse`` and ``SimpleTemplateResponse``
    
  3. ===================================================
    
  4. 
    
  5. .. module:: django.template.response
    
  6.    :synopsis: Classes dealing with lazy-rendered HTTP responses.
    
  7. 
    
  8. Standard :class:`~django.http.HttpResponse` objects are static structures.
    
  9. They are provided with a block of pre-rendered content at time of
    
  10. construction, and while that content can be modified, it isn't in a form that
    
  11. makes it easy to perform modifications.
    
  12. 
    
  13. However, it can sometimes be beneficial to allow decorators or
    
  14. middleware to modify a response *after* it has been constructed by the
    
  15. view. For example, you may want to change the template that is used,
    
  16. or put additional data into the context.
    
  17. 
    
  18. TemplateResponse provides a way to do just that. Unlike basic
    
  19. :class:`~django.http.HttpResponse` objects, TemplateResponse objects retain
    
  20. the details of the template and context that was provided by the view to
    
  21. compute the response. The final output of the response is not computed until
    
  22. it is needed, later in the response process.
    
  23. 
    
  24. ``SimpleTemplateResponse`` objects
    
  25. ==================================
    
  26. 
    
  27. .. class:: SimpleTemplateResponse()
    
  28. 
    
  29. Attributes
    
  30. ----------
    
  31. 
    
  32. .. attribute:: SimpleTemplateResponse.template_name
    
  33. 
    
  34.     The name of the template to be rendered. Accepts a backend-dependent
    
  35.     template object (such as those returned by
    
  36.     :func:`~django.template.loader.get_template()`), the name of a template,
    
  37.     or a list of template names.
    
  38. 
    
  39.     Example: ``['foo.html', 'path/to/bar.html']``
    
  40. 
    
  41. .. attribute:: SimpleTemplateResponse.context_data
    
  42. 
    
  43.     The context data to be used when rendering the template. It must be a
    
  44.     :class:`dict`.
    
  45. 
    
  46.     Example: ``{'foo': 123}``
    
  47. 
    
  48. .. attribute:: SimpleTemplateResponse.rendered_content
    
  49. 
    
  50.     The current rendered value of the response content, using the current
    
  51.     template and context data.
    
  52. 
    
  53. .. attribute:: SimpleTemplateResponse.is_rendered
    
  54. 
    
  55.     A boolean indicating whether the response content has been rendered.
    
  56. 
    
  57. Methods
    
  58. -------
    
  59. 
    
  60. .. method:: SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None, charset=None, using=None, headers=None)
    
  61. 
    
  62.     Instantiates a :class:`~django.template.response.SimpleTemplateResponse`
    
  63.     object with the given template, context, content type, HTTP status, and
    
  64.     charset.
    
  65. 
    
  66.     ``template``
    
  67.         A backend-dependent template object (such as those returned by
    
  68.         :func:`~django.template.loader.get_template()`), the name of a template,
    
  69.         or a list of template names.
    
  70. 
    
  71.     ``context``
    
  72.         A :class:`dict` of values to add to the template context. By default,
    
  73.         this is an empty dictionary.
    
  74. 
    
  75.     ``content_type``
    
  76.         The value included in the HTTP ``Content-Type`` header, including the
    
  77.         MIME type specification and the character set encoding. If
    
  78.         ``content_type`` is specified, then its value is used. Otherwise,
    
  79.         ``'text/html'`` is used.
    
  80. 
    
  81.     ``status``
    
  82.         The HTTP status code for the response.
    
  83. 
    
  84.     ``charset``
    
  85.         The charset in which the response will be encoded. If not given it will
    
  86.         be extracted from ``content_type``, and if that is unsuccessful, the
    
  87.         :setting:`DEFAULT_CHARSET` setting will be used.
    
  88. 
    
  89.     ``using``
    
  90.         The :setting:`NAME <TEMPLATES-NAME>` of a template engine to use for
    
  91.         loading the template.
    
  92. 
    
  93.     ``headers``
    
  94.         A :class:`dict` of HTTP headers to add to the response.
    
  95. 
    
  96. .. method:: SimpleTemplateResponse.resolve_context(context)
    
  97. 
    
  98.     Preprocesses context data that will be used for rendering a template.
    
  99.     Accepts a :class:`dict` of context data. By default, returns the same
    
  100.     :class:`dict`.
    
  101. 
    
  102.     Override this method in order to customize the context.
    
  103. 
    
  104. .. method:: SimpleTemplateResponse.resolve_template(template)
    
  105. 
    
  106.     Resolves the template instance to use for rendering. Accepts a
    
  107.     backend-dependent template object (such as those returned by
    
  108.     :func:`~django.template.loader.get_template()`), the name of a template,
    
  109.     or a list of template names.
    
  110. 
    
  111.     Returns the backend-dependent template object instance to be rendered.
    
  112. 
    
  113.     Override this method in order to customize template loading.
    
  114. 
    
  115. .. method:: SimpleTemplateResponse.add_post_render_callback()
    
  116. 
    
  117.     Add a callback that will be invoked after rendering has taken
    
  118.     place. This hook can be used to defer certain processing
    
  119.     operations (such as caching) until after rendering has occurred.
    
  120. 
    
  121.     If the :class:`~django.template.response.SimpleTemplateResponse`
    
  122.     has already been rendered, the callback will be invoked
    
  123.     immediately.
    
  124. 
    
  125.     When called, callbacks will be passed a single argument -- the
    
  126.     rendered :class:`~django.template.response.SimpleTemplateResponse`
    
  127.     instance.
    
  128. 
    
  129.     If the callback returns a value that is not ``None``, this will be
    
  130.     used as the response instead of the original response object (and
    
  131.     will be passed to the next post rendering callback etc.)
    
  132. 
    
  133. .. method:: SimpleTemplateResponse.render()
    
  134. 
    
  135.     Sets ``response.content`` to the result obtained by
    
  136.     :attr:`SimpleTemplateResponse.rendered_content`, runs all post-rendering
    
  137.     callbacks, and returns the resulting response object.
    
  138. 
    
  139.     ``render()`` will only have an effect the first time it is called. On
    
  140.     subsequent calls, it will return the result obtained from the first call.
    
  141. 
    
  142. 
    
  143. ``TemplateResponse`` objects
    
  144. ============================
    
  145. 
    
  146. .. class:: TemplateResponse()
    
  147. 
    
  148.     ``TemplateResponse`` is a subclass of
    
  149.     :class:`~django.template.response.SimpleTemplateResponse` that knows about
    
  150.     the current :class:`~django.http.HttpRequest`.
    
  151. 
    
  152. Methods
    
  153. -------
    
  154. 
    
  155. .. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, charset=None, using=None, headers=None)
    
  156. 
    
  157.     Instantiates a :class:`~django.template.response.TemplateResponse` object
    
  158.     with the given request, template, context, content type, HTTP status, and
    
  159.     charset.
    
  160. 
    
  161.     ``request``
    
  162.         An :class:`~django.http.HttpRequest` instance.
    
  163. 
    
  164.     ``template``
    
  165.         A backend-dependent template object (such as those returned by
    
  166.         :func:`~django.template.loader.get_template()`), the name of a template,
    
  167.         or a list of template names.
    
  168. 
    
  169.     ``context``
    
  170.         A :class:`dict` of values to add to the template context. By default,
    
  171.         this is an empty dictionary.
    
  172. 
    
  173.     ``content_type``
    
  174.         The value included in the HTTP ``Content-Type`` header, including the
    
  175.         MIME type specification and the character set encoding. If
    
  176.         ``content_type`` is specified, then its value is used. Otherwise,
    
  177.         ``'text/html'`` is used.
    
  178. 
    
  179.     ``status``
    
  180.         The HTTP status code for the response.
    
  181. 
    
  182.     ``charset``
    
  183.         The charset in which the response will be encoded. If not given it will
    
  184.         be extracted from ``content_type``, and if that is unsuccessful, the
    
  185.         :setting:`DEFAULT_CHARSET` setting will be used.
    
  186. 
    
  187.     ``using``
    
  188.         The :setting:`NAME <TEMPLATES-NAME>` of a template engine to use for
    
  189.         loading the template.
    
  190. 
    
  191.     ``headers``
    
  192.         A :class:`dict` of HTTP headers to add to the response.
    
  193. 
    
  194. The rendering process
    
  195. =====================
    
  196. 
    
  197. Before a :class:`~django.template.response.TemplateResponse` instance can be
    
  198. returned to the client, it must be rendered. The rendering process takes the
    
  199. intermediate representation of template and context, and turns it into the
    
  200. final byte stream that can be served to the client.
    
  201. 
    
  202. There are three circumstances under which a ``TemplateResponse`` will be
    
  203. rendered:
    
  204. 
    
  205. * When the ``TemplateResponse`` instance is explicitly rendered, using
    
  206.   the :meth:`SimpleTemplateResponse.render()` method.
    
  207. 
    
  208. * When the content of the response is explicitly set by assigning
    
  209.   ``response.content``.
    
  210. 
    
  211. * After passing through template response middleware, but before
    
  212.   passing through response middleware.
    
  213. 
    
  214. A ``TemplateResponse`` can only be rendered once. The first call to
    
  215. :meth:`SimpleTemplateResponse.render` sets the content of the response;
    
  216. subsequent rendering calls do not change the response content.
    
  217. 
    
  218. However, when ``response.content`` is explicitly assigned, the
    
  219. change is always applied. If you want to force the content to be
    
  220. re-rendered, you can reevaluate the rendered content, and assign
    
  221. the content of the response manually::
    
  222. 
    
  223.     # Set up a rendered TemplateResponse
    
  224.     >>> from django.template.response import TemplateResponse
    
  225.     >>> t = TemplateResponse(request, 'original.html', {})
    
  226.     >>> t.render()
    
  227.     >>> print(t.content)
    
  228.     Original content
    
  229. 
    
  230.     # Re-rendering doesn't change content
    
  231.     >>> t.template_name = 'new.html'
    
  232.     >>> t.render()
    
  233.     >>> print(t.content)
    
  234.     Original content
    
  235. 
    
  236.     # Assigning content does change, no render() call required
    
  237.     >>> t.content = t.rendered_content
    
  238.     >>> print(t.content)
    
  239.     New content
    
  240. 
    
  241. Post-render callbacks
    
  242. ---------------------
    
  243. 
    
  244. Some operations -- such as caching -- cannot be performed on an
    
  245. unrendered template. They must be performed on a fully complete and
    
  246. rendered response.
    
  247. 
    
  248. If you're using middleware, you can do that. Middleware provides
    
  249. multiple opportunities to process a response on exit from a view. If
    
  250. you put behavior in the response middleware, it's guaranteed to execute
    
  251. after template rendering has taken place.
    
  252. 
    
  253. However, if you're using a decorator, the same opportunities do not
    
  254. exist. Any behavior defined in a decorator is handled immediately.
    
  255. 
    
  256. To compensate for this (and any other analogous use cases),
    
  257. :class:`TemplateResponse` allows you to register callbacks that will
    
  258. be invoked when rendering has completed. Using this callback, you can
    
  259. defer critical processing until a point where you can guarantee that
    
  260. rendered content will be available.
    
  261. 
    
  262. To define a post-render callback, define a function that takes
    
  263. a single argument -- response -- and register that function with
    
  264. the template response::
    
  265. 
    
  266.     from django.template.response import TemplateResponse
    
  267. 
    
  268.     def my_render_callback(response):
    
  269.         # Do content-sensitive processing
    
  270.         do_post_processing()
    
  271. 
    
  272.     def my_view(request):
    
  273.         # Create a response
    
  274.         response = TemplateResponse(request, 'mytemplate.html', {})
    
  275.         # Register the callback
    
  276.         response.add_post_render_callback(my_render_callback)
    
  277.         # Return the response
    
  278.         return response
    
  279. 
    
  280. ``my_render_callback()`` will be invoked after the ``mytemplate.html``
    
  281. has been rendered, and will be provided the fully rendered
    
  282. :class:`TemplateResponse` instance as an argument.
    
  283. 
    
  284. If the template has already been rendered, the callback will be
    
  285. invoked immediately.
    
  286. 
    
  287. Using ``TemplateResponse`` and ``SimpleTemplateResponse``
    
  288. =========================================================
    
  289. 
    
  290. A :class:`TemplateResponse` object can be used anywhere that a normal
    
  291. :class:`django.http.HttpResponse` can be used. It can also be used as an
    
  292. alternative to calling :func:`~django.shortcuts.render()`.
    
  293. 
    
  294. For example, the following view returns a :class:`TemplateResponse` with a
    
  295. template and a context containing a queryset::
    
  296. 
    
  297.     from django.template.response import TemplateResponse
    
  298. 
    
  299.     def blog_index(request):
    
  300.         return TemplateResponse(request, 'entry_list.html', {'entries': Entry.objects.all()})