upgrading.txt 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. =================================
  2. Upgrading templates to Django 1.8
  3. =================================
  4. Django's template system was overhauled in Django 1.8 when it gained support
  5. for multiple template engines. This document complements the :doc:`release
  6. notes </releases/1.8>` with detailed upgrade instructions on some topics.
  7. The :setting:`TEMPLATES` settings
  8. =================================
  9. A new setting was introduced in Django 1.8: :setting:`TEMPLATES`. All existing
  10. template-related settings were deprecated.
  11. During the deprecation period, Django will create a backwards-compatible
  12. :setting:`TEMPLATES` based on the ``TEMPLATE_*`` settings if you don't define
  13. it yourself.
  14. Here's how to define :setting:`TEMPLATES` in your settings module.
  15. If you're using the default value of ``TEMPLATE_LOADERS``, that is, if it
  16. isn't defined in your settings file or if it's set to::
  17. ['django.template.loaders.filesystem.Loader',
  18. 'django.template.loaders.app_directories.Loader']
  19. then you should define :setting:`TEMPLATES` as follows::
  20. TEMPLATES = [
  21. {
  22. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  23. 'DIRS': [
  24. # insert your TEMPLATE_DIRS here
  25. ],
  26. 'APP_DIRS': True,
  27. 'OPTIONS': {
  28. 'context_processors': [
  29. # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
  30. # list if you haven't customized them:
  31. 'django.contrib.auth.context_processors.auth',
  32. 'django.template.context_processors.debug',
  33. 'django.template.context_processors.i18n',
  34. 'django.template.context_processors.media',
  35. 'django.template.context_processors.static',
  36. 'django.template.context_processors.tz',
  37. 'django.contrib.messages.context_processors.messages',
  38. ],
  39. },
  40. },
  41. ]
  42. If you aren't using the default value of ``TEMPLATE_LOADERS``, then you should
  43. define :setting:`TEMPLATES` as follows::
  44. TEMPLATES = [
  45. {
  46. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  47. 'DIRS': [
  48. # insert your TEMPLATE_DIRS here
  49. ],
  50. 'OPTIONS': {
  51. 'context_processors': [
  52. # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
  53. # list if you haven't customized them:
  54. 'django.contrib.auth.context_processors.auth',
  55. 'django.template.context_processors.debug',
  56. 'django.template.context_processors.i18n',
  57. 'django.template.context_processors.media',
  58. 'django.template.context_processors.static',
  59. 'django.template.context_processors.tz',
  60. 'django.contrib.messages.context_processors.messages',
  61. ],
  62. 'loaders': [
  63. # insert your TEMPLATE_LOADERS here
  64. ]
  65. },
  66. },
  67. ]
  68. Furthermore you should replace ``django.core.context_processors`` with
  69. ``django.template.context_processors`` in the names of context processors.
  70. If your settings module defines ``ALLOWED_INCLUDE_ROOTS`` or
  71. ``TEMPLATE_STRING_IF_INVALID``, include their values under the
  72. ``'allowed_include_roots'`` and ``'string_if_invalid'`` keys in the
  73. ``'OPTIONS'`` dictionary.
  74. If it sets ``TEMPLATE_DEBUG`` to a value that differs from :setting:`DEBUG`,
  75. include that value under the ``'debug'`` key in ``'OPTIONS'``.
  76. Once you have defined :setting:`TEMPLATES`, you can safely remove
  77. ``ALLOWED_INCLUDE_ROOTS``, ``TEMPLATE_CONTEXT_PROCESSORS``,
  78. ``TEMPLATE_DEBUG``, ``TEMPLATE_DIRS``, ``TEMPLATE_LOADERS``, and
  79. ``TEMPLATE_STRING_IF_INVALID``.
  80. If you are overriding some of these settings in tests, you should override the
  81. entire :setting:`TEMPLATES` setting instead.
  82. :mod:`django.template.loader`
  83. =============================
  84. .. _get_template-upgrade-django-18:
  85. :func:`~django.template.loader.get_template` and :func:`~django.template.loader.select_template`
  86. ------------------------------------------------------------------------------------------------
  87. In Django 1.8 :func:`~django.template.loader.get_template` and
  88. :func:`~django.template.loader.select_template` return a backend-dependent
  89. ``Template`` instead of a :class:`django.template.Template`.
  90. For example, if :func:`~django.template.loader.get_template` loads a template
  91. with a :class:`~django.template.backends.django.DjangoTemplates` backend, then
  92. it returns a ``django.template.backends.django.Template``.
  93. ``Template`` objects must provide a
  94. :meth:`~django.template.backends.base.Template.render` method whose signature
  95. differs slightly from the Django template language's
  96. :meth:`~django.template.Template.render`.
  97. Instead of::
  98. from django.template import Context
  99. from django.template.loader import get_template
  100. template = get_template('hello.html')
  101. html = template.render(Context({'name': 'world'}))
  102. You should write::
  103. from django.template.loader import get_template
  104. template = get_template('hello.html')
  105. html = template.render({'name': 'world'})
  106. And instead of::
  107. from django.template import RequestContext
  108. from django.template.loader import get_template
  109. template = get_template('hello.html')
  110. html = template.render(RequestContext(request, {'name': 'world'}))
  111. You should write::
  112. from django.template.loader import get_template
  113. template = get_template('hello.html')
  114. html = template.render({'name': 'world'}, request)
  115. Passing a :class:`~django.template.Context` or a
  116. :class:`~django.template.RequestContext` is still possible when the template
  117. is loaded by a :class:`~django.template.backends.django.DjangoTemplates`
  118. backend but it's deprecated and won't be supported in Django 1.10.
  119. If you're loading a template while you're rendering another template with the
  120. Django template language and you have access to the current context, for
  121. instance in the ``render()`` method of a template tag, you can use the current
  122. :class:`~django.template.Engine` directly. Instead of::
  123. from django.template.loader import get_template
  124. template = get_template('included.html')
  125. You can write::
  126. template = context.template.engine.get_template('included.html')
  127. This will load the template with the current engine without triggering the
  128. multiple template engines machinery, which is usually the desired behavior.
  129. Unlike previous solutions, this returns a :class:`django.template.Template`,
  130. like :func:`~django.template.loader.get_template` used to in Django 1.7 and
  131. earlier, avoiding all backwards-compatibility problems.
  132. ``get_template_from_string()``
  133. ------------------------------
  134. Private API ``get_template_from_string(template_code)`` was removed in Django
  135. 1.8 because it had no way to choose an engine to compile the template.
  136. Three alternatives are available.
  137. If you control the project's setting, you can use one of the configured
  138. engines::
  139. from django.template import engines
  140. template = engines['django'].from_string(template_code)
  141. This returns a backend-dependent ``Template`` object.
  142. For trivial templates that don't need context processors nor anything else,
  143. you can create a bare-bones engine and use its ``from_string()`` method::
  144. from django.template import Engine
  145. template = Engine().from_string(template_code)
  146. This returns a :class:`django.template.Template` because
  147. :class:`~django.template.Engine` is part of the Django template language's
  148. APIs. The multiple template engines machinery isn't involved here.
  149. Finally, if you have access to the current context, you can use the same trick
  150. as above::
  151. template = context.template.engine.from_string(template_code)
  152. ``Template()``
  153. ==============
  154. To a lesser extent, instantiating a template with ``Template(template_code)``
  155. suffers from the same issue as ``get_template_from_string()``.
  156. It still works when the :setting:`TEMPLATES` setting defines exactly one
  157. :class:`~django.template.backends.django.DjangoTemplates` backend, but
  158. pluggable applications can't control this requirement.
  159. The last two solutions described in the previous section are recommended in
  160. that case.