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.