Commit 3d495cfd authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Added release notes and upgrade instructions for templates.

parent ee8d5b91
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ material, see :doc:`/topics/templates` topic guide.
   language
   builtins
   api
   upgrading

.. seealso::

+187 −0
Original line number Diff line number Diff line
=================================
Upgrading templates to Django 1.8
=================================

Django's template system was overhauled in Django 1.8 when it gained support
for multiple template engines. This document complements the :doc:`release
notes </releases/1.8>` with detailed upgrade instructions on some topics.

The :setting:`TEMPLATES` settings
=================================

A new setting was introduced in Django 1.8: :setting:`TEMPLATES`. All existing
template-related settings except :setting:`TEMPLATE_DEBUG` were deprecated.

During the deprecation period, Django will create a backwards-compatible
:setting:`TEMPLATES` based on the ``TEMPLATE_*`` settings if you don't define
it yourself.

Here's how to define :setting:`TEMPLATES` in your settings module.

If you're using the default value of ``TEMPLATE_LOADERS``, that is, if it
isn't defined in your settings file or if it's set to::

    ('django.template.loaders.filesystem.Loader',
     'django.template.loaders.app_directories.Loader')

then you should define :setting:`TEMPLATES` as follows::

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [
                # insert your TEMPLATE_DIRS here
            ],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
                    # list if you haven't customized them:
                    'django.contrib.auth.context_processors.auth',
                    'django.template.context_processors.debug',
                    'django.template.context_processors.i18n',
                    'django.template.context_processors.media',
                    'django.template.context_processors.static',
                    'django.template.context_processors.tz',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]

If you aren't using the default value of ``TEMPLATE_LOADERS``, then you should
define :setting:`TEMPLATES` as follows::

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [
                # insert your TEMPLATE_DIRS here
            ],
            'OPTIONS': {
                'context_processors': [
                    # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
                    # list if you haven't customized them:
                    'django.contrib.auth.context_processors.auth',
                    'django.template.context_processors.debug',
                    'django.template.context_processors.i18n',
                    'django.template.context_processors.media',
                    'django.template.context_processors.static',
                    'django.template.context_processors.tz',
                    'django.contrib.messages.context_processors.messages',
                ],
                'loaders': [
                    # insert your TEMPLATE_LOADERS here
                ]
            },
        },
    ]

Furthermore you should replace ``django.core.context_processors`` with
``django.template.context_processors`` in the names of context processors.

If your settings module defines ``ALLOWED_INCLUDE_ROOTS`` or
``TEMPLATE_STRING_IF_INVALID``, include their values under the
``'allowed_include_roots'`` and ``'string_if_invalid'`` keys in the
``'OPTIONS'`` dictionary.

Once you have defined :setting:`TEMPLATES`, you can safely remove
``ALLOWED_INCLUDE_ROOTS``, ``TEMPLATE_CONTEXT_PROCESSORS``, ``TEMPLATE_DIRS``,
``TEMPLATE_LOADERS``, and ``TEMPLATE_STRING_IF_INVALID``.

If you are overriding some of these settings in tests, you should override the
entire :setting:`TEMPLATES` setting instead.

:mod:`django.template.loader`
=============================

:func:`~django.template.loader.get_template` and :func:`~django.template.loader.select_template`
------------------------------------------------------------------------------------------------

In Django 1.8 :func:`~django.template.loader.get_template` and
:func:`~django.template.loader.select_template` returns a backend-dependent
``Template`` instead of a :class:`django.template.Template`.

``Template`` objects must provide a
:meth:`~django.template.backends.base.Template.render` method whose signature
differs slightly from the Django template language's
:meth:`~django.template.Template.render`.

Instead of::

    from django.template import Context
    from django.template.loader import get_template

    template = get_template('hello.html')
    html = template.render(Context({'name': 'world'}))

You should write::

    from django.template.loader import get_template

    template = get_template('hello.html')
    html = template.render({'name': 'world'})

And instead of::

    from django.template import RequestContext
    from django.template.loader import get_template

    template = get_template('hello.html')
    html = template.render(RequestContext(request, {'name': 'world'}))

You should write::

    from django.template.loader import get_template

    template = get_template('hello.html')
    html = template.render({'name': 'world'}, request)

Passing a :class:`~django.template.Context` or a
:class:`~django.template.RequestContext` is still possible when the template
is loaded by a :class:`~django.template.backends.django.DjangoTemplates`
backend but it's deprecated and won't be supported in Django 2.0.

If you're loading a template while you're rendering another template with the
Django template language and you have access to the current context, for
instance in the ``render()`` method of a template tag, you can use the current
:class:`~django.template.Engine` directly. Instead of::


    from django.template.loader import get_template
    template = get_template('included.html')

You can write::

    template = context.engine.get_template('included.html')

This will load the template with the current engine without triggering the
multiple template engines machinery, which is usually the desired behavior.

``get_template_from_string()``
------------------------------

Private API ``get_template_from_string(template_code)`` was removed in Django
1.8 because it had no way to choose an engine to compile the template. There
are two solutions to replace it.

You can use a template engine's ``from_string()`` method::

    from django.template import engines

    template = engines['django'].from_string(template_code)

Or you can use the same trick as above, if you have access to the current
context::

    template = context.engine.from_string(template_code)

Or you can instantiate a :class:`~django.template.Template` directly::

    from django.template import Template

    template = Template(template_code)

The last solution requires that :setting:`TEMPLATES` defines exactly one
:class:`~django.template.backends.django.DjangoTemplates` backend. That engine
will automatically be used to render the template.
+11 −0
Original line number Diff line number Diff line
@@ -45,6 +45,17 @@ new official API have been deprecated and will eventually be removed. A
:ref:`guide to migrating from the old API to the new API
<migrating-old-meta-api>` has been provided.

Multiple template engines
~~~~~~~~~~~~~~~~~~~~~~~~~

Django 1.8 defines a stable API for integrating template backends. It includes
built-in support for the Django template language and for Jinja2_. It supports
rendering templates with multiple engines within the same project. Learn more
about the new features in the :doc:`topic guide </topics/templates>` and check
the :doc:`upgrade instructions </ref/templates/upgrading>` for details.

.. _Jinja2: http://jinja.pocoo.org/

Security enhancements
~~~~~~~~~~~~~~~~~~~~~