Mise à jour des gabarits pour Django 1.8

Le système des gabarits de Django a été retravaillé dans Django 1.8 afin de pouvoir accepter plusieurs moteurs de gabarit. Ce document complète les notes de publication avec des instructions de mise à jour détaillées sur certains sujets.

Les réglages TEMPLATES

Un nouveau réglage a été introduit dans Django 1.8 : TEMPLATES. Tous les réglages existants liés aux gabarits ont été rendus obsolètes.

Durant la période d’obsolescence, Django crée un réglage TEMPLATES rétrocompatible sur la base des réglages TEMPLATE_* si vous ne l’avez pas fait vous-même.

Voici comment définir TEMPLATES dans votre module de réglages.

Si vous utilisez la valeur par défaut de TEMPLATE_LOADERS, c’est-à-dire s’il n’est pas défini dans vos réglages ou qu’il est défini comme :

['django.template.loaders.filesystem.Loader',
 'django.template.loaders.app_directories.Loader']

voici alors comment définir TEMPLATES:

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',
            ],
        },
    },
]

Si vous n’utilisez pas la valeur par défaut de TEMPLATE_LOADERS, voici comment vous devez définir TEMPLATES:

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
            ]
        },
    },
]

De plus, vous devez remplacer django.core.context_processors par django.template.context_processors dans les noms des processeurs de contexte.

Si votre module de réglages définit ALLOWED_INCLUDE_ROOTS ou TEMPLATE_STRING_IF_INVALID, incluez leur valeur dans les clés ‘allowed_include_roots’` et 'string_if_invalid' du dictionnaire 'OPTIONS'.

Si le réglage TEMPLATE_DEBUG contient une valeur différente de DEBUG, incluez sa valeur dans la clé 'debug' du dictionnaire 'OPTIONS'.

Après avoir défini TEMPLATES, vous pouvez sans problème supprimer ALLOWED_INCLUDE_ROOTS, TEMPLATE_CONTEXT_PROCESSORS, TEMPLATE_DEBUG, TEMPLATE_DIRS, TEMPLATE_LOADERS et TEMPLATE_STRING_IF_INVALID.

Si vous surchargez certains de ces réglages dans des tests, il est nécessaire de surcharger maintenant la totalité de TEMPLATES.

django.template.loader

get_template() et select_template()

Dans Django 1.8, get_template() et select_template() renvoient un objet Template dépendant du moteur au lieu de django.template.Template.

Par exemple, si get_template() charge un gabarit avec un moteur DjangoTemplates, c’est un objet django.template.backends.django.Template qui est renvoyé.

Les objets Template doivent fournir une méthode render() dont la signature diffère légèrement de la méthode render() du langage de gabarit de Django.

Au lieu de :

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

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

Vous devriez écrire :

from django.template.loader import get_template

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

Et au lieu de :

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

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

Vous devriez écrire :

from django.template.loader import get_template

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

La transmission d’un Context ou d’un RequestContext est toujours possible lorsque le gabarit est chargé par un moteur DjangoTemplates, mais cette possibilité est obsolète et ne sera plus prise en charge dans Django 1.10.

Si vous chargez un gabarit lorsque vous êtes en train de produire un autre gabarit avec le langage de gabarit de Django et que vous avez accès au contexte courant, par exemple dans la méthode render() d’une balise de gabarit, vous pouvez utiliser le moteur Engine actuel directement. Au lieu de :

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

Vous pouvez écrire :

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

Cela va charger le gabarit avec le moteur actuel sans faire appel à la machinerie des moteurs de gabarits multiples, ce qui est généralement le comportement souhaité. Au contraire des solutions précédentes, ceci renvoie un objet django.template.Template, comme le faisait get_template() dans les versions de Django jusqu’à 1.7, ce qui évite tout problème de rétrocompatibilité.

get_template_from_string()

L’API privée get_template_from_string(template_code) a été supprimée dans Django 1.8 parce qu’il n’était pas possible de choisir un moteur pour compiler le gabarit.

Trois alternatives sont disponibles.

Si vous contrôlez les réglages du projet, vous pouvez utiliser l’un des moteurs configurés :

from django.template import engines

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

Cela renvoie un objet Template dépendant du moteur.

Pour les gabarits simplistes qui n’ont pas besoin de processeur de contexte ni aucune autre spécialité, vous pouvez créer un moteur élémentaire et utiliser sa méthode from_string():

from django.template import Engine

template = Engine().from_string(template_code)

Cela renvoie un django.template.Template car Engine fait partie de l’API du langage de gabarit de Django. La machinerie des moteurs de gabarits multiples n’est pas concernée ici.

Finalement, si vous avez accès au contexte en cours, vous pouvez utiliser la même astuce que ci-dessus :

template = context.template.engine.from_string(template_code)

Template()

À un degré moindre, la création d’une instance de gabarit avec Template(template_code) souffre des mêmes problèmes que get_template_from_string().

Cela fonctionne toujours lorsque le réglage TEMPLATES définit exactement un moteur DjangoTemplates, mais les applications réutilisables ne peuvent pas contrôler cette exigence.

Les deux dernières solutions décrites dans la section précédente sont recommandées dans ce cas.

Back to Top