---
title: "Le langage de gabarit de Django : pour les programmeurs Python"
version: 3.0
locale: fr
source: https://docs.djangoproject.com/fr/3.0/ref/templates/api/
canonical: https://djangodocs.dev/fr/3.0/ref/templates/api/
---
# Le langage de gabarit de Django : pour les programmeurs Python

Ce document présente le système de gabarits de Django dans une perspective technique : son fonctionnement et ses possibilités d’extension. Si vous recherchez la référence de la syntaxe du langage, consultez [Le langage de gabarit de Django](/fr/3.0/ref/templates/language/).

Il présuppose une compréhension des gabarits, des contextes, des variables, des balises et du rendu des gabarits. Commencez par l”[introduction au langage de gabarit de Django](/fr/3.0/topics/templates/#template-language-intro) si ces concepts ne vous sont pas familiers.

## Aperçu

L’utilisation du système de gabarits en Python est un processus à trois étapes :

1. Vous configurez un moteur [`Engine`](#django.template.Engine).
2. Vous compilez le code du gabarit en un objet [`Template`](#django.template.Template).
3. Vous produisez ce gabarit en fonction d’un [`Context`](#django.template.Context).

Les projets Django se basent généralement sur l”[API de haut niveau et indépendante du moteur](/fr/3.0/topics/templates/#template-engines) pour chacune de ces étapes plutôt que d’employer l’API de bas niveau du système des gabarits :

1. Pour chaque moteur [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates) du réglage [`TEMPLATES`](/fr/3.0/ref/settings/#std-setting-TEMPLATES), Django crée une instance [`Engine`](#django.template.Engine). [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates) englobe [`Engine`](#django.template.Engine) et l’adapte à l’API commune des moteurs de gabarits.
2. Le module [`django.template.loader`](/fr/3.0/topics/templates/#module-django.template.loader) fournit des fonctions telles que [`get_template()`](/fr/3.0/topics/templates/#django.template.loader.get_template) pour le chargement des gabarits. Elles renvoient un `django.template.backends.django.Template` qui adapte l’objet [`django.template.Template`](#django.template.Template) réel.
3. Le gabarit `Template` obtenu à l’étape précédente possède une méthode [`render()`](/fr/3.0/topics/templates/#django.template.backends.base.Template.render) qui produit un contexte et éventuellement une requête dans un objet [`Context`](#django.template.Context) et délègue le rendu à l’objet [`Template`](#django.template.Template) sous-jacent.

## Configuration d’un moteur

Si vous utilisez le moteur [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates), cette documentation n’est probablement pas celle que vous cherchez. Une instance de la classe `Engine` décrite ci-dessous est accessible en utilisant l’attribut `engine` du moteur, et toute valeur par défaut d’attribut mentionnée plus bas est remplacée par ce qui est transmis par [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates).

#### `class Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None, autoescape=True)`

Lors de la création d’une instance de `Engine`, tous les paramètres doivent être transmis sous forme de paramètres nommés :

- `dirs` définit une liste de répertoires dans lesquels le moteur recherche des fichiers sources de gabarits. Cette liste est utilisée pour configurer [`filesystem.Loader`](#django.template.loaders.filesystem.Loader).

  La valeur par défaut est une liste vide.
- `app_dirs` n’affecte que la valeur par défaut de `loaders`. Voir ci-dessous.

  Sa valeur par défaut est `False`.
- `autoescape` contrôle si l’auto-échappement HTML est activé.

  Sa valeur par défaut est `True`.

  > **Warning**
  >
  > Ne la mettez à `False` que si vous produisez des gabarits non HTML !
- `context_processors` est une liste de chemins Python pointés vers des objets exécutables utilisés pour remplir le contexte lorsqu’un gabarit est produit avec une requête. Ces exécutables acceptent un objet requête comme paramètre et renvoient un dictionnaire d’éléments à fusionner dans le contexte.

  La valeur par défaut est une liste vide.

  Voir [`RequestContext`](#django.template.RequestContext) pour plus d’informations.
- `debug` est une valeur booléenne qui active ou désactive le mode débogage des gabarits. Quand elle vaut `True`, le moteur de gabarit stocke des informations de débogage supplémentaires pouvant être utilisées pour afficher un rapport détaillé lors de toute exception générée durant le rendu des gabarits.

  Sa valeur par défaut est `False`.
- `loaders` est une liste de classes de chargeurs de gabarits, sous forme de chaînes. Chaque classe `Loader` sait comment importer les gabarits d’une source particulière. Il est possible d’indiquer des tuples au lieu de chaînes. Le premier élément du tuple correspond au nom de classe de `Loader` alors que les éléments suivants seront transmis à la classe `Loader` en vue de son initialisation.

  Sa valeur par défaut est une liste contenant :

  - `'django.template.loaders.filesystem.Loader'`
  - `'django.template.loaders.app_directories.Loader'` si et seulement si `app_dirs` vaut `True`.

  Si `debug` vaut `False`, ces chargeurs sont enveloppés par [`django.template.loaders.cached.Loader`](#django.template.loaders.cached.Loader).

  Voir [Types de chargeurs](#template-loaders) pour les détails.
- `string_if_invalid` est le résultat, sous forme de chaîne de caractères, que le système des gabarits utilise pour remplacer le contenu de variables non valides (par ex. mal orthographiées).

  Sa valeur par défaut est une chaîne vide.

  Voir [Traitement des variables non valides](#invalid-template-variables) pour les détails.
- `file_charset` est le jeu de caractères utilisé pour lire les fichiers de gabarits depuis le disque.

  Sa valeur par défaut est `'utf-8'`.
- `'libraries'`: un dictionnaire d’étiquettes et de chemins Python pointés de modules de balises de gabarit à inscrire auprès du moteur de gabarit. Ceci est utilisé pour ajouter de nouvelles bibliothèques ou pour fournir des étiquettes alternatives à celles qui existent. Par exemple :

  ```
  Engine(
      libraries={
          'myapp_tags': 'path.to.myapp.tags',
          'admin.urls': 'django.contrib.admin.templatetags.admin_urls',
      },
  )
  ```

  Les bibliothèques peuvent être chargées en passant la clé de dictionnaire correspondante à la balise [`{% load %}`](/fr/3.0/ref/templates/builtins/#std-templatetag-load).
- `'builtins'`: une liste de chemins Python pointés de modules de balises de gabarit à ajouter aux [modules intégrés](/fr/3.0/ref/templates/builtins/). Par exemple :

  ```
  Engine(
      builtins=['myapp.builtins'],
  )
  ```

  Les balises et les filtres des bibliothèques intégrées peuvent être utilisés sans devoir d’abord faire appel à la balise [`{% load %}`](/fr/3.0/ref/templates/builtins/#std-templatetag-load).

#### `static Engine.get_default()`

Renvoie le moteur [`Engine`](#django.template.Engine) sous-jacent du premier moteur [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates) configuré. Génère [`ImproperlyConfigured`](/fr/3.0/ref/exceptions/#django.core.exceptions.ImproperlyConfigured) si aucun moteur n’a été configuré.

C’est obligatoire pour préserver les API qui comptent sur un moteur configuré implicitement et globalement disponible. Toute autre utilisation est fortement découragée.

#### `Engine.from_string(template_code)`

Compile le code du gabarit donné et renvoie un objet [`Template`](#django.template.Template).

#### `Engine.get_template(template_name)`

Charge un gabarit ayant le nom donné, le compile et renvoie un objet [`Template`](#django.template.Template).

#### `Engine.select_template(template_name_list)`

Comme [`get_template()`](#django.template.Engine.get_template), sauf qu’il accepte une liste de noms et renvoie le premier gabarit existant de la liste.

## Chargement d’un gabarit

La manière recommandée de créer un [`Template`](#django.template.Template) est d’appeler les méthodes de fabrication du moteur [`Engine`](#django.template.Engine): [`get_template()`](#django.template.Engine.get_template), [`select_template()`](#django.template.Engine.select_template) et [`from_string()`](#django.template.Engine.from_string).

Dans un projet Django où le réglage [`TEMPLATES`](/fr/3.0/ref/settings/#std-setting-TEMPLATES) définit un moteur [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates), il est possible d’instancier directement un objet [`Template`](#django.template.Template). Si plus d’un moteur [`DjangoTemplates`](/fr/3.0/topics/templates/#django.template.backends.django.DjangoTemplates) est défini, c’est le premier qui sera utilisé.

#### `class Template`

Cette classe se trouve dans `django.template.Template`. Le constructeur accepte un paramètre, le code brut du gabarit :

```
from django.template import Template

template = Template("My name is {{ my_name }}.")
```

> **En coulisses**
>
> Le système n’analyse qu’une seule fois le code brut du gabarit, au moment de la création de l’objet `Template`. Par la suite, le résultat est stocké en interne sous forme de structure arborescente pour des raisons de performance.
>
> Même l’analyse en soi est assez rapide. La plupart de l’analyse se déroule dans un seul appel à une seule et courte expression régulière.

## Rendu d’un contexte

À partir du moment où vous avez un objet [`Template`](#django.template.Template) compilé, vous pouvez procéder au rendu d’un contexte. Vous pouvez réutiliser le même gabarit pour le produire à plusieurs reprises avec différents contextes.

#### `class Context(dict_=None)`

Le constructeur de `django.template.Context` accepte un paramètre facultatif — un dictionnaire faisant correspondre des noms de variables à leurs valeurs.

Pour plus de détails, voir [Manipulation des objets Context](#playing-with-context) plus bas.

#### `Template.render(context)`

Appelez la méthode `render()` de l’objet [`Template`](#django.template.Template) avec un [`Context`](#django.template.Context) qui doit « remplir » le gabarit :

```
>>> from django.template import Context, Template
>>> template = Template("My name is {{ my_name }}.")

>>> context = Context({"my_name": "Adrian"})
>>> template.render(context)
"My name is Adrian."

>>> context = Context({"my_name": "Dolores"})
>>> template.render(context)
"My name is Dolores."
```

### Variables et sous-éléments

Les noms de variables peuvent contenir des lettres (A-Z), des chiffres (0-9), des soulignements et des points (mais elles ne peuvent pas commencer par un soulignement).

Les points ont une signification particulière dans le rendu des gabarits. Un point dans un nom de variable indique l’accès à un sous-élément. Plus précisément, lorsque le système de gabarit voit un point dans un nom de variable, il recherche des sous-éléments dans cet ordre :

- Accès dictionnaire. Exemple : `foo["bar"]`
- Accès attribut. Exemple : `foo.bar`
- Accès par index de liste. Exemple : `foo[bar]`

Notez que « bar » dans une expression de gabarit comme `{{ foo.bar }}` est interprété comme une chaîne littérale et même si une variable « bar » existe dans le contexte du gabarit, elle ne sera pas appelée.

Le système de gabarits utilise le premier accès qui fonctionne. C’est une logique de court-circuit. Voici quelques exemples :

```
>>> from django.template import Context, Template
>>> t = Template("My name is {{ person.first_name }}.")
>>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}}
>>> t.render(Context(d))
"My name is Joe."

>>> class PersonClass: pass
>>> p = PersonClass()
>>> p.first_name = "Ron"
>>> p.last_name = "Nasty"
>>> t.render(Context({"person": p}))
"My name is Ron."

>>> t = Template("The first stooge in the list is {{ stooges.0 }}.")
>>> c = Context({"stooges": ["Larry", "Curly", "Moe"]})
>>> t.render(c)
"The first stooge in the list is Larry."
```

Si un élément de la variable est un objet exécutable, le système de gabarits essaye de l’appeler. Exemple :

```
>>> class PersonClass2:
...     def name(self):
...         return "Samantha"
>>> t = Template("My name is {{ person.name }}.")
>>> t.render(Context({"person": PersonClass2}))
"My name is Samantha."
```

Les variables exécutables sont légèrement plus complexes que les variables qui ne demandent que des accès directs. Voici quelques éléments à garder en tête :

- Si la variable génère une exception quand elle est appelée, celle-ci est propagée, sauf si l’exception possède un attribut `silent_variable_failure` valant `True`. Dans ce dernier cas, la variable produira une chaîne équivalente au contenu de l’option de configuration `string_if_invalid` du moteur (chaîne vide par défaut). Exemple :

  ```
  >>> t = Template("My name is {{ person.first_name }}.")
  >>> class PersonClass3:
  ...     def first_name(self):
  ...         raise AssertionError("foo")
  >>> p = PersonClass3()
  >>> t.render(Context({"person": p}))
  Traceback (most recent call last):
  ...
  AssertionError: foo

  >>> class SilentAssertionError(Exception):
  ...     silent_variable_failure = True
  >>> class PersonClass4:
  ...     def first_name(self):
  ...         raise SilentAssertionError
  >>> p = PersonClass4()
  >>> t.render(Context({"person": p}))
  "My name is ."
  ```

  Notez que [`django.core.exceptions.ObjectDoesNotExist`](/fr/3.0/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist), qui est la classe de base de toutes les exceptions `DoesNotExist` de l’API de base de données de Django, contient `silent_variable_failure = True`. Ainsi, si vous utilisez les gabarits de Django avec des objets modèles de Django, toute exception `DoesNotExist` échoue silencieusement.
- Une variable ne peut être appelée que si elle ne demande pas de paramètre. Sinon le système renvoie la valeur de l’option `string_if_invalid` du moteur.

- Des effets de bord peuvent se produire lors de l’appel à certaines variables et il serait insensé ou sécuritairement désastreux de permettre au système de gabarits d’y accéder.

  Un bon exemple est la méthode [`delete()`](/fr/3.0/ref/models/instances/#django.db.models.Model.delete) de chaque objet modèle de Django. Le système de gabarits ne devrait pas permettre de faire quelque chose comme :

  ```
  I will now delete this valuable data. {{ data.delete }}
  ```

  Pour empêcher cela, définissez un attribut `alters_data` sur la variable exécutable. Le système de gabarits n’appellera pas une variable si elle contient `alters_data=True` et la remplace plutôt par le contenu de `string_if_invalid`, sans conditions. Les méthodes générées dynamiquement [`delete()`](/fr/3.0/ref/models/instances/#django.db.models.Model.delete) et [`save()`](/fr/3.0/ref/models/instances/#django.db.models.Model.save) sur les objets modèles de Django reçoivent automatiquement `alters_data=True`. Exemple :

  ```
  def sensitive_function(self):
      self.database_record.delete()
  sensitive_function.alters_data = True
  ```
- Vous pouvez parfois avoir envie de désactiver cette fonctionnalité pour d’autres raisons, et dire au système de gabarits de ne pas interpréter une variable, peu importe le contexte. Pour ce faire, il faut définir un attribut `do_not_call_in_templates` sur la variable exécutable, avec la valeur `True`. Le système de gabarits va alors considérer que la variable ne peut pas être appelée (ce qui permet par exemple d’accéder aux attributs de l’objet exécutable).

### Traitement des variables non valides

Généralement, si une variable n’existe pas, le système des gabarits insère la valeur de l’option de configuration `string_if_invalid` du moteur, qui vaut  `''` (chaîne vide) par défaut.

Les filtres appliqués à une variable non valide ne seront appliqués que si `string_if_invalid` est défini à `''` (la chaîne vide). Si `string_if_invalid` est défini à une autre valeur, les filtres de variable seront ignorés.

Ce comportement est légèrement différent pour les balises de gabarit `if`, `for` et `regroup`. Si une variable non valide est fournie à l’une de ces balises de gabarit, la variable sera interprétée comme `None`. Les filtres sont toujours appliqués aux variables non valides dans ces balises de gabarit.

Si `string_if_invalid` contient un substituant `'%s'`, ce dernier sera remplacé par le nom de la variable non valide.

> **À des fins de débogage uniquement !**
>
> Bien que `string_if_invalid` puisse être un outil de débogage utile, il n’est pas conseillé de l’activer de manière permanente durant le développement.
>
> Beaucoup de gabarits, y compris certains de Django, comptent sur le comportement silencieux du système de gabarit lorsqu’une variable non existante apparaît. Si `string_if_invalid` contient une valeur autre que `''`, vous allez rencontrer des problèmes d’affichage avec ces gabarits et ces sites.
>
> Généralement, `string_if_invalid` ne devrait être activé que pour déboguer un problème spécifique d’un gabarit, puis réinitialisé une fois cette phase terminée.

### Variables intégrées

Tous les contextes contiennent `True`, `False` et `None`. Comme on peut s’y attendre, ces variables correspondent aux objets Python équivalents.

### Restrictions avec les chaînes littérales

Le langage de gabarit de Django ne possède pas de moyen pour échapper les caractères utilisés pour sa propre syntaxe. Par exemple, la balise [`templatetag`](/fr/3.0/ref/templates/builtins/#std-templatetag-templatetag) est indispensable pour afficher des séquences de caractères comme `{%` ou `%}`.

Un problème similaire survient lorsqu’il s’agit d’inclure ces séquences dans les paramètres d’un filtre ou d’une balise. Par exemple, lors de l’analyse d’un bloc de balise, l’analyseur de gabarit de Django cherche la première occurrence de `%}` après un `{%`. Cela empêche de pouvoir utiliser `"%}"` dans une chaîne littérale. Par exemple, une exception `TemplateSyntaxError` est générée pour les expressions suivantes :

```
{% include "template.html" tvar="Some string literal with %} in it." %}

{% with tvar="Some string literal with %} in it." %}{% endwith %}
```

La même problématique est révélée quand on utilise une séquence réservée dans les paramètres d’un filtre :

```
{{ some.variable|default:"}}" }}
```

Si vous avez besoin d’utiliser des chaînes qui contiennent ces séquences, vous devez les stocker dans des variables de gabarit ou utiliser une balise ou un filtre personnalisé pour détourner cette restriction.

## Manipulation des objets `Context`

La plupart du temps, les objets [`Context`](#django.template.Context) sont créés en transmettant à `Context()` un dictionnaire contenant les données utiles. Mais il est toujours possible d’ajouter ou d’enlever des éléments d’un objet `Context` après sa création, en employant la syntaxe habituelle des dictionnaires :

```
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']
>>> c['foo']
Traceback (most recent call last):
...
KeyError: 'foo'
>>> c['newvariable'] = 'hello'
>>> c['newvariable']
'hello'
```

#### `Context.get(key, otherwise=None)`

Renvoie la valeur correspondant à `key` si `key` est dans le contexte, sinon renvoie `otherwise`.

#### `Context.setdefault(key, default=None)`

Si `key` est dans le contexte, renvoie sa valeur. Sinon insère `key` avec la valeur `default` et renvoie `default`.

#### `Context.pop()`

#### `Context.push()`

#### `exception ContextPopException`

Un objet `Context` est une pile. C’est-à-dire que vous pouvez lui appliquer les méthodes `push()` et `pop()`. En cas de `pop()` en trop, une exception `django.template.ContextPopException` est générée :

```
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.push()
{}
>>> c['foo'] = 'second level'
>>> c['foo']
'second level'
>>> c.pop()
{'foo': 'second level'}
>>> c['foo']
'first level'
>>> c['foo'] = 'overwritten'
>>> c['foo']
'overwritten'
>>> c.pop()
Traceback (most recent call last):
...
ContextPopException
```

Vous pouvez aussi utiliser `push()` comme gestionnaire de contexte pour garantir que l’instruction `pop()` correspondante soit effectivement appelée.

```
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.push():
...     c['foo'] = 'second level'
...     c['foo']
'second level'
>>> c['foo']
'first level'
```

Tous les paramètres passés à `push()` sont transmis au constructeur de `dict` utilisé pour construire le nouveau niveau de contexte.

```
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.push(foo='second level'):
...     c['foo']
'second level'
>>> c['foo']
'first level'
```

#### `Context.update(other_dict)`

En plus de `push()` et `pop()`, l’objet `Context` définit également une méthode `update()`. Elle fonctionne comme `push()`, mais accepte en paramètre un dictionnaire et place ce dictionnaire sur la pile, au lieu d’un dictionnaire vide.

```
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.update({'foo': 'updated'})
{'foo': 'updated'}
>>> c['foo']
'updated'
>>> c.pop()
{'foo': 'updated'}
>>> c['foo']
'first level'
```

Comme `push()`, vous pouvez utiliser `update()` comme gestionnaire de contexte pour garantir que l’instruction `pop()` correspondante soit effectivement appelée.

```
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.update({'foo': 'second level'}):
...     c['foo']
'second level'
>>> c['foo']
'first level'
```

L’utilisation de `Context` comme une pile est bien pratique avec [certaines balises de gabarit personnalisées](/fr/3.0/howto/custom-template-tags/#howto-writing-custom-template-tags).

#### `Context.flatten()`

En utilisant la méthode `flatten()`, vous pouvez obtenir l’ensemble de la pile de `Context` sous forme d’un unique dictionnaire, y compris les variables natives.

```
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.update({'bar': 'second level'})
{'bar': 'second level'}
>>> c.flatten()
{'True': True, 'None': None, 'foo': 'first level', 'False': False, 'bar': 'second level'}
```

La méthode `flatten()` est aussi utilisée en interne pour rendre les objets `Context` comparables.

```
>>> c1 = Context()
>>> c1['foo'] = 'first level'
>>> c1['bar'] = 'second level'
>>> c2 = Context()
>>> c2.update({'bar': 'second level', 'foo': 'first level'})
{'foo': 'first level', 'bar': 'second level'}
>>> c1 == c2
True
```

Le résultat de `flatten()` peut être utile dans les tests unitaires pour comparer `Context` avec un `dict`:

```
class ContextTest(unittest.TestCase):
    def test_against_dictionary(self):
        c1 = Context()
        c1['update'] = 'value'
        self.assertEqual(c1.flatten(), {
            'True': True,
            'None': None,
            'False': False,
            'update': 'value',
        })
```

### Utilisation de `RequestContext`

#### `class RequestContext(request, dict_=None, processors=None)`

Django contient une classe `Context` spéciale, `django.template.RequestContext`, qui se comporte légèrement différemment de l’objet `django.template.Context` normal. La première différence est qu’elle demande un objet [`HttpRequest`](/fr/3.0/ref/request-response/#django.http.HttpRequest) comme premier paramètre. Par exemple :

```
c = RequestContext(request, {
    'foo': 'bar',
})
```

La seconde différence est qu’elle remplit automatiquement le contexte avec quelques variables, en fonction de l’option de configuration `context_processors` du moteur.

L’option `context_processors` est une liste d’objets exécutables appelés **processeurs de contexte** qui acceptent un objet requête en paramètre et renvoient un dictionnaire d’éléments à fusionner dans le contexte. Dans le fichier de réglages généré par défaut, le moteur de gabarit par défaut contient les processeurs de contexte suivants :

```
[
    'django.template.context_processors.debug',
    'django.template.context_processors.request',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
]
```

En plus de ce contenu, [`RequestContext`](#django.template.RequestContext) active toujours `'django.template.context_processors.csrf'`. Il s’agit d’un processeur de contexte lié à la sécurité exigé par l’application d’administration ainsi que d’autres applications contribuées. Il est volontairement ajouté de force pour qu’il ne puisse pas être enlevé par une erreur de configuration dans l’option `context_processors`.

Chaque processeur est appliqué successivement. Cela signifie que si un processeur ajoute une variable au contexte et que le processeur suivant ajoute une variable de même nom, la seconde écrase la première. Les processeurs par défaut sont présentés ci-dessous.

> **Quand les processeurs de contexte sont-ils appliqués ?**
>
> Les processeurs de contexte sont appliqués au sommet des données de contexte. Cela signifie qu’un processeur de contexte peut écraser une variable que vous avez fournie dans un objet [`Context`](#django.template.Context) ou [`RequestContext`](#django.template.RequestContext), il faut donc faire attention de ne pas utiliser des variables dont le nom peut entrer en conflit avec ceux des processeurs de contexte installés.
>
> Si vous souhaitez que des données de contexte aient la priorité sur les processeurs de contexte, utilisez le schéma suivant :
>
> ```
> from django.template import RequestContext
>
> request_context = RequestContext(request)
> request_context.push({"my_name": "Adrian"})
> ```
>
> Django fait cela pour permettre aux données de contexte d’écraser des processeurs de contexte dans des API comme [`render()`](/fr/3.0/topics/http/shortcuts/#django.shortcuts.render) ou [`TemplateResponse`](/fr/3.0/ref/template-response/#django.template.response.TemplateResponse).

Il est également possible de donner à [`RequestContext`](#django.template.RequestContext) une liste de processeurs supplémentaires en utilisant le troisième paramètre positionnel facultatif, `processors`. Dans cet exemple, l’instance [`RequestContext`](#django.template.RequestContext) reçoit une variable `ip_address`:

```
from django.http import HttpResponse
from django.template import RequestContext, Template

def ip_address_processor(request):
    return {'ip_address': request.META['REMOTE_ADDR']}

def client_ip_view(request):
    template = Template('{{ title }}: {{ ip_address }}')
    context = RequestContext(request, {
        'title': 'Your IP Address',
    }, [ip_address_processor])
    return HttpResponse(template.render(context))
```

### Processeurs de contexte de gabarit intégrés

Voici ce que font chacun des processeurs de contexte intégrés :

#### `django.contrib.auth.context_processors.auth`

#### `auth()`

Si ce processeur est activé, chaque `RequestContext` contiendra ces variables :

- `user` – une instance `auth.User` représentant l’utilisateur actuellement connecté (ou une instance `AnonymousUser`, si le client n’est pas connecté).
- `perms` – une instance de `django.contrib.auth.context_processors.PermWrapper`, représentant les permissions de l’utilisateur actuellement connecté.

#### `django.template.context_processors.debug`

#### `debug()`

Si ce processeur est activé, chaque `RequestContext` contient ces deux variables – mais seulement si le réglage [`DEBUG`](/fr/3.0/ref/settings/#std-setting-DEBUG) vaut `True` et que l’adresse IP de la requête (`request.META['REMOTE_ADDR']`) se trouve dans le réglage [`INTERNAL_IPS`](/fr/3.0/ref/settings/#std-setting-INTERNAL_IPS):

- `debug` – `True`. Vous pouvez l’utiliser dans les gabarits pour tester si vous êtes en mode  [`DEBUG`](/fr/3.0/ref/settings/#std-setting-DEBUG).
- `sql_queries` – une liste de dictionnaires `{'sql': ..., 'time': ...}` représentant chaque requête SQL effectuée jusque-là dans le traitement de la requête et le temps nécessaire à son exécution. La liste est triée par alias de base de données, puis par requête. Elle est produite de manière différée au moment de son accès.

#### `django.template.context_processors.i18n`

#### `i18n()`

Si ce processeur est activé, chaque `RequestContext` contiendra ces variables :

- `LANGUAGES` – la valeur du réglage [`LANGUAGES`](/fr/3.0/ref/settings/#std-setting-LANGUAGES).
- `LANGUAGE_BIDI` – `True`, si la langue actuelle est une langue s’écrivant de droite à gauche, comme l’hébreu ou l’arabe. `False` s’il s’agit d’une langue s’écrivant de gauche à droite, comme l’anglais, le français ou l’allemand.
- `LANGUAGE_CODE` – `request.LANGUAGE_CODE`, si elle existe. Sinon, la valeur du réglage [`LANGUAGE_CODE`](/fr/3.0/ref/settings/#std-setting-LANGUAGE_CODE).

Voir [balises de gabarits i18n](/fr/3.0/topics/i18n/translation/#i18n-template-tags) pour des balises de gabarits qui génèrent les mêmes valeurs.

#### `django.template.context_processors.media`

Si ce processeur est activé, chaque `RequestContext` contiendra une variable `MEDIA_URL`, équivalente au réglage [`MEDIA_URL`](/fr/3.0/ref/settings/#std-setting-MEDIA_URL).

#### `django.template.context_processors.static`

#### `static()`

Si ce processeur est activé, chaque `RequestContext` contiendra une variable `STATIC_URL`, équivalente au réglage [`STATIC_URL`](/fr/3.0/ref/settings/#std-setting-STATIC_URL).

#### `django.template.context_processors.csrf`

Ce processeur ajoute un jeton requis par la balise de gabarit [`csrf_token`](/fr/3.0/ref/templates/builtins/#std-templatetag-csrf_token) pour se protéger des attaques de type [Cross Site Request Forgeries](/fr/3.0/ref/csrf/).

#### `django.template.context_processors.request`

Si ce processeur est activé, chaque `RequestContext` contiendra une variable `request` correspondant à l’objet [`HttpRequest`](/fr/3.0/ref/request-response/#django.http.HttpRequest) actuel.

#### `django.template.context_processors.tz`

#### `tz()`

Si ce processeur est activé, chaque `RequestContext` contiendra une variable `TIME_ZONE`, fournissant le nom du fuseau horaire actuellement actif.

#### `django.contrib.messages.context_processors.messages`

Si ce processeur est activé, chaque `RequestContext` contiendra ces deux variables :

- `messages` – une liste de messages (sous forme de chaînes) qui ont été définis au travers de l”[infrastructure des messages](/fr/3.0/ref/contrib/messages/).
- `DEFAULT_MESSAGE_LEVELS` – un tableau de correspondance entre les noms de niveaux de message et leur [valeur numérique](/fr/3.0/ref/contrib/messages/#message-level-constants).

### Écriture de son propre processeur de contexte

Un processeur de contexte possède une interface simple : il s’agit d’une fonction Python acceptant un paramètre, un objet [`HttpRequest`](/fr/3.0/ref/request-response/#django.http.HttpRequest), et renvoyant un dictionnaire qui est ensuite ajouté au contexte de gabarit. Chaque processeur de contexte *doit* renvoyer un dictionnaire.

Les processeurs de contexte personnalisés peuvent se trouver n’importe où dans le code. Tout ce que Django demande, c’est que l’option `'context_processors'` du réglage [`TEMPLATES`](/fr/3.0/ref/settings/#std-setting-TEMPLATES) (ou le paramètre `context_processors` d’un moteur [`Engine`](#django.template.Engine) si vous l’utilisez directement) contienne le chemin vers le processeur personnalisé.

## Chargement des gabarits

En général, il est conseillé de stocker les gabarits sur le système de fichiers plutôt que de faire appel à l’API [`Template`](#django.template.Template) de bas niveau. Les gabarits doivent se trouver dans un répertoire désigné comme **répertoire de gabarits**.

Django recherche les répertoires de gabarits à plusieurs endroits, en fonction des réglages de chargement des gabarits (voir « Types de chargeurs » ci-dessous), mais la façon la plus élémentaire de désigner des répertoires de gabarits est d’utiliser l’option [`DIRS`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-DIRS).

### L’option [`DIRS`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-DIRS)

Indiquez à Django quels sont vos répertoires de gabarits en utilisant l’option [`DIRS`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-DIRS) du réglage [`TEMPLATES`](/fr/3.0/ref/settings/#std-setting-TEMPLATES) dans votre fichier de réglages, ou le paramètre `dirs` de [`Engine`](#django.template.Engine). Il devrait contenir une liste de chaînes contenant les chemins complets vers les répertoires de gabarits :

```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            '/home/html/templates/lawrence.com',
            '/home/html/templates/default',
        ],
    },
]
```

Les gabarits peuvent se trouver n’importe où, pour autant que leur emplacement soit lisible par le serveur Web. Leur extension est également à votre bon plaisir, `.html`, `.txt`, ou même sans extension du tout.

Notez que ces chemins doivent utiliser les barres obliques de style Unix, même avec Windows.

### Types de chargeurs

Par défaut, Django utilise un chargeur de gabarit basé sur le système de fichiers, mais il existe également quelques autres chargeurs de gabarit, qui savent comment charger des gabarits à partir d’autres sources.

Certains de ces autres chargeurs sont désactivés par défaut, mais vous pouvez les activer en ajoutant une option `'loaders'` à votre moteur `DjangoTemplates` dans le réglage [`TEMPLATES`](/fr/3.0/ref/settings/#std-setting-TEMPLATES) ou en transmettant un paramètre `loaders` à [`Engine`](#django.template.Engine). `loaders` doit contenir une liste de chaînes ou de tuples, où chaque élément représente une classe de chargeur de gabarit. Voici les chargeurs de gabarit que Django propose :

`django.template.loaders.filesystem.Loader`

#### `class filesystem.Loader`

Charge les gabarits à partir du système de fichiers, en fonction de [`DIRS`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-DIRS).

Ce chargeur est actif par défaut. Cependant, il ne trouvera aucun gabarit tant que vous n’aurez pas défini [`DIRS`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-DIRS) à une liste non vide :

```
TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
}]
```

Il est aussi possible de surcharger `'DIRS'` et de définir des répertoires spécifiques à un chargeur basé sur le système de fichiers :

```
TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'OPTIONS': {
        'loaders': [
            (
                'django.template.loaders.filesystem.Loader',
                [os.path.join(BASE_DIR, 'templates')],
            ),
        ],
    },
}]
```

`django.template.loaders.app_directories.Loader`

#### `class app_directories.Loader`

Charge les gabarits à partir des dossiers d’applications Django sur le système de fichiers. Pour chaque application dans [`INSTALLED_APPS`](/fr/3.0/ref/settings/#std-setting-INSTALLED_APPS), le chargeur cherche un sous-répertoire nommé `templates`. S’il le trouve, Django recherche les gabarits dans ce répertoire.

Cela signifie que vous pouvez stocker les gabarits à l’intérieur des différentes applications. Cela facilite également la distribution des applications Django dotées de gabarits par défaut.

Par exemple, avec ce réglage :

```
INSTALLED_APPS = ['myproject.polls', 'myproject.music']
```

…`get_template('foo.html')` recherche  `foo.html` dans ces répertoires, dans l’ordre :

- `/chemin/vers/myproject/polls/templates/`
- `/chemin/vers/myproject/music/templates/`

… et utilise le premier qu’il trouve.

L’ordre de [`INSTALLED_APPS`](/fr/3.0/ref/settings/#std-setting-INSTALLED_APPS) est important ! Par exemple, si vous souhaitez personnaliser l’administration de Django, il peut être utile de surcharger le gabarit `admin/base_site.html` standard de `django.contrib.admin` par votre propre `admin/base_site.html` dans `myproject.polls`. Vous devez alors vous assurer que `myproject.polls` apparaisse *avant* `django.contrib.admin` dans [`INSTALLED_APPS`](/fr/3.0/ref/settings/#std-setting-INSTALLED_APPS), sinon `django.contrib.admin` sera chargé en premier et votre gabarit sera ignoré.

Notez que le chargeur effectue une optimisation lors de son premier lancement : il place en cache une liste des paquets [`INSTALLED_APPS`](/fr/3.0/ref/settings/#std-setting-INSTALLED_APPS) qui possèdent un sous-répertoire `templates`.

Vous pouvez activer ce chargeur en définissant [`APP_DIRS`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-APP_DIRS) à `True`:

```
TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'APP_DIRS': True,
}]
```

`django.template.loaders.cached.Loader`

#### `class cached.Loader`

Par défaut (lorsque [`DEBUG`](/fr/3.0/ref/settings/#std-setting-DEBUG) vaut `True`), le système des gabarits lit et compile les gabarits chaque fois qu’ils sont produits. Même si le système des gabarits de Django est assez rapide, la charge de lecture et de compilation des gabarits peut être conséquente.

Le chargeur de gabarits « en cache » est configuré en lui donnant une liste d’autres chargeurs qu’il va encapsuler. Les chargeurs encapsulés sont utilisés pour retrouver les gabarits inconnus la première fois qu’ils sont référencés. Le chargeur « en cache » stocke ensuite l’objet `Template` compilé en mémoire. Cette instance mise en cache est renvoyée lors de chaque nouvelle requête de chargement de ce même gabarit.

Ce chargeur est automatiquement activé si [`OPTIONS['loaders']`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-OPTIONS) n’est pas défini et que [`OPTIONS['debug']`](/fr/3.0/ref/settings/#std-setting-TEMPLATES-OPTIONS) vaut `False` (cette dernière option contient par défaut la valeur de [`DEBUG`](/fr/3.0/ref/settings/#std-setting-DEBUG)).

Il est aussi possible d’activer le cache de gabarits avec des chargeurs de gabarit personnalisés en utilisant des réglages comme ceci :

```
TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    'OPTIONS': {
        'loaders': [
            ('django.template.loaders.cached.Loader', [
                'django.template.loaders.filesystem.Loader',
                'django.template.loaders.app_directories.Loader',
                'path.to.custom.Loader',
            ]),
        ],
    },
}]
```

> **Note**
>
> Toutes les balises de gabarit intégrées à Django peuvent être utilisées sans problème avec le chargeur « en cache », mais si vous utilisez des balises de gabarit personnalisées provenant de paquets externes ou que vous avez écrites vous-même, il est nécessaire de vérifier que l’implémentation des objets `Node` de chaque balise respecte la concurrence (« thread-safe »). Pour plus d’informations, consultez les indications sur la [concurrence entre fils d’exécution dans les balises de gabarit](/fr/3.0/howto/custom-template-tags/#template-tag-thread-safety).

`django.template.loaders.locmem.Loader`

#### `class locmem.Loader`

Charge des gabarits à partir d’un dictionnaire Python. Utile pour les tests.

Ce chargeur prend un dictionnaire de gabarits comme premier paramètre :

```
TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'OPTIONS': {
        'loaders': [
            ('django.template.loaders.locmem.Loader', {
                'index.html': 'content here',
            }),
        ],
    },
}]
```

Ce chargeur est désactivé par défaut.

Django utilise les chargeurs de gabarit dans l’ordre de leur apparition dans l’option `'loaders'`. Il utilise chaque chargeur jusqu’à ce qu’il trouve une correspondance.

## Chargeurs personnalisés

Il est possible de charger des gabarits provenant de sources supplémentaires en utilisant des chargeurs de gabarit personnalisés. Les classes personnalisées de `Loader` doivent hériter de `django.template.loaders.base.Loader` et définir les méthodes `get_contents()` et `get_template_sources()`.

### Méthodes des chargeurs

#### `class Loader`

Charge des gabarits à partir d’une source donnée, telle que le système de fichier ou une base de données.

#### `get_template_sources(template_name)`

Une méthode acceptant un nom de gabarit `template_name` et renvoyant une à une des instances [`Origin`](#django.template.base.Origin) pour chaque source possible.

Par exemple, le chargeur système de fichiers pourrait recevoir `'index.html'` comme paramètre `template_name`. Cette méthode produirait des origines pour le chemin complet de `index.html` tel qu’il devrait apparaître dans chaque répertoire de gabarits que le chargeur inspecte.

La méthode n’a pas besoin de vérifier que le gabarit existe pour un chemin donné, mais elle doit s’assurer que le chemin est valide. Par exemple, le chargeur système de fichiers doit s’assurer que le chemin se trouve bien dans un répertoire de gabarits valide.

#### `get_contents(origin)`

Renvoie le contenu d’un gabarit en fonction d’une instance [`Origin`](#django.template.base.Origin) donnée.

C’est ici qu’un chargeur système de fichiers lit le contenu à partir du système de fichiers, ou qu’un chargeur base de données lit à partir de la base de données. Si aucun gabarit existant ne correspond, une erreur [`TemplateDoesNotExist`](/fr/3.0/topics/templates/#django.template.TemplateDoesNotExist) doit être générée.

#### `get_template(template_name, skip=None)`

Renvoie un objet `Template` correspondant à `template_name` en passant en boucle ce que [`get_template_sources()`](#django.template.loaders.base.Loader.get_template_sources) renvoie et en appelant [`get_contents()`](#django.template.loaders.base.Loader.get_contents). Le premier gabarit trouvé est renvoyé. Si aucun n’est trouvé, une exception [`TemplateDoesNotExist`](/fr/3.0/topics/templates/#django.template.TemplateDoesNotExist) est générée.

Le paramètre facultatif `skip` est une liste d’origines à ignorer lors de l’extension des gabarits. Cela permet à des gabarits d’étendre d’autres gabarits du même nom. Une autre utilité est d’éviter les erreurs de récursion.

En général, il est suffisant que les chargeurs de gabarit personnalisés définissent [`get_template_sources()`](#django.template.loaders.base.Loader.get_template_sources) et [`get_contents()`](#django.template.loaders.base.Loader.get_contents). `get_template()` n’a généralement pas besoin d’être surchargée.

> **Création de son propre chargeur**
>
> Pour des exemples, lisez le [code source des chargeurs intégrés à Django](https://github.com/django/django/blob/stable/3.0.x/django/template/loaders).

## Origine de gabarit

Les gabarits possèdent un attribut `origin` contenant des attributs qui dépendent de la source à partir de laquelle ils ont été chargés.

#### `class Origin(name, template_name=None, loader=None)`

#### `name`

Le chemin du gabarit tel que renvoyé par le chargeur de gabarit. Pour les chargeurs qui lisent à partir du système de fichiers, il s’agit du chemin complet correspondant au gabarit.

Si le gabarit est instancié directement plutôt que par l’intermédiaire d’un chargeur de gabarits, ce chemin contient `<unknown_source>` (source inconnue).

#### `template_name`

Le chemin relatif du gabarit tel que transmis au chargeur de gabarits.

Si le gabarit est instancié directement plutôt que par l’intermédiaire d’un chargeur de gabarits, cette valeur vaut `None`.

#### `loader`

L’instance de chargeur de gabarits qui a construit cette `Origin`.

Si le gabarit est instancié directement plutôt que par l’intermédiaire d’un chargeur de gabarits, cette valeur vaut `None`.

[`django.template.loaders.cached.Loader`](#django.template.loaders.cached.Loader) exige que tous les chargeurs qu’elle enveloppe définissent cet attribut, typiquement en créant l’instance `Origin` avec `loader=self`.
