---
title: "Intergiciels (« Middleware »)"
version: 1.9
locale: fr
source: https://docs.djangoproject.com/fr/1.9/topics/http/middleware/
canonical: https://djangodocs.dev/fr/1.9/topics/http/middleware/
---
# Intergiciels (« Middleware »)

Les intergiciels représentent un système de points d’entrée dans le traitement des requêtes et des réponses de Django. C’est un système de greffons léger et de bas niveau pour modifier de façon globale les entrées et sorties HTTP de Django.

Chaque composant d’intergiciel est responsable d’effectuer une tâche spécifique. Par exemple, Django contient un intergiciel, [`AuthenticationMiddleware`](/fr/1.9/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware), qui associe les utilisateurs aux requêtes et aux sessions.

Ce document explique comment fonctionnent les intergiciels, la manière de les activer et d’écrire vos propres intergiciels. Django est livré avec quelques intergiciels intégrés qu’il est possible d’utiliser tels quels. Ils sont documentés dans la [référence des intergiciels intégrés](/fr/1.9/ref/middleware/).

## Activation des intergiciels

Pour activer un intergiciel, ajoutez son chemin dans la liste [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES) de vos réglages Django.

Dans [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES), chaque intergiciel est représenté par une chaîne : le chemin Python complet vers le nom de la classe d’intergiciel. Par exemple, voici la valeur par défaut créée par [`django-admin startproject`](/fr/1.9/ref/django-admin/#django-admin-startproject):

```
MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```

Une installation de Django n’a pas nécessairement des intergiciels, [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES) pouvant très bien être vide si vous le souhaitez, mais il est fortement recommandé d’utiliser au moins [`CommonMiddleware`](/fr/1.9/ref/middleware/#django.middleware.common.CommonMiddleware).

L’ordre dans [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES) a son importance car un intergiciel peut dépendre d’un autre. Par exemple, [`AuthenticationMiddleware`](/fr/1.9/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware) stocke l’utilisateur non authentifié dans la session ; il doit donc être exécuté après [`SessionMiddleware`](/fr/1.9/ref/middleware/#django.contrib.sessions.middleware.SessionMiddleware). Voir [Ordre des intergiciels](/fr/1.9/ref/middleware/#middleware-ordering) pour d’autres indications utiles concernant l’ordre des classes d’intergiciel de Django.

## Points d’entrée et ordre des applications

Durant la phase de requête, avant d’appeler la vue, Django applique les intergiciels dans l’ordre où ils sont définis dans [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES), de haut en bas. Deux points d’entrée sont disponibles :

- [`process_request()`](#process_request)
- [`process_view()`](#process_view)

Durant la phase de réponse, après avoir appelé la vue, Django applique les intergiciels dans l’ordre inverse de leur définition, de bas en haut. Trois points d’entrée sont disponibles :

- [`process_exception()`](#process_exception) (seulement si la vue a généré une exception)
- [`process_template_response()`](#process_template_response) (seulement pour les réponses basées sur des gabarits)
- [`process_response()`](#process_response)

[![middleware application order](topics/http/_images/middleware.svg)](../../../../../../_images/middleware.svg)

Si vous préférez, on peut comparer ce système à un oignon : chaque classe d’intergiciel est une « pelure » qui englobe la vue.

Le comportement de chaque point d’entrée est décrit ci-dessous.

## Écriture de son propre intergiciel

Il est facile d’écrire un intergiciel. Chaque intergiciel est une classe Python unique qui définit l’une ou plusieurs des méthodes suivantes :

### `process_request()`

#### `process_request(request)`

`request` est un objet [`HttpRequest`](/fr/1.9/ref/request-response/#django.http.HttpRequest).

`process_request()` est appelée pour chaque requête, avant que Django ne décide quelle vue exécuter.

Elle doit renvoyer soit `None`, soit un objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse). Si elle renvoie `None`, Django continue le traitement de la requête, en appliquant d’éventuels autres intergiciels `process_request()`, puis les intergiciels `process_view()` et pour terminer exécute la vue appropriée. Si elle renvoie un objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse), Django n’applique plus aucun intergiciel de requête, de vue ou d’exception, ni la vue correspondante ; il va simplement appliquer les intergiciels de réponse à cet objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse) et renvoyer le résultat.

### `process_view()`

#### `process_view(request, view_func, view_args, view_kwargs)`

`request` est un objet [`HttpRequest`](/fr/1.9/ref/request-response/#django.http.HttpRequest). `view_func` et la fonction python que Django s’apprête à utiliser (il s’agit bien de l’objet fonction, pas du nom textuel de la fonction). `view_args` est une liste de paramètres positionnels qui seront transmis à la vue, et `view_kwargs` est un dictionnaire de paramètres nommés qui seront transmis à la vue. Ni `view_args` ni `view_kwargs` ne comprennent le premier paramètre de la vue (`request`).

`process_view()` est appelée juste avant que Django n’appelle la vue.

Elle doit renvoyer soit `None`, soit un objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse). Si elle renvoie `None`, Django continue le traitement de la requête, en appliquant d’éventuels autres intergiciels `process_view()`, puis exécute la vue appropriée. Si elle renvoie un objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse), Django n’applique plus aucun intergiciel de vue ou d’exception, ni la vue correspondante ; il va simplement appliquer les intergiciels de réponse à cet objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse) et renvoyer le résultat.

> **Note**
>
> L’accès à [`request.POST`](/fr/1.9/ref/request-response/#django.http.HttpRequest.POST) depuis un intergiciel dans ses méthodes `process_request` ou `process_view` empêche toute vue exécutée après les intergiciels de pouvoir [modifier les gestionnaires de téléversement de la requête](/fr/1.9/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly), et devrait donc être évité.
>
> La classe [`CsrfViewMiddleware`](/fr/1.9/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware) peut être considérée comme une exception, car elle fournit les décorateurs [`csrf_exempt()`](/fr/1.9/ref/csrf/#django.views.decorators.csrf.csrf_exempt) et [`csrf_protect()`](/fr/1.9/ref/csrf/#django.views.decorators.csrf.csrf_protect) qui permettent aux vues de contrôler explicitement le moment de la validation CSRF.

### `process_template_response()`

#### `process_template_response(request, response)`

`request` est un objet [`HttpRequest`](/fr/1.9/ref/request-response/#django.http.HttpRequest). `response` est l’objet [`TemplateResponse`](/fr/1.9/ref/template-response/#django.template.response.TemplateResponse) (ou équivalent) renvoyé par une vue Django ou par un intergiciel.

`process_template_response()` est appelée juste après la fin de l’exécution de la vue, pour autant que l’instance réponse possède une méthode `render()`, ce qui laisse penser qu’il s’agit d’un objet [`TemplateResponse`](/fr/1.9/ref/template-response/#django.template.response.TemplateResponse) ou d’un équivalent.

Elle doit renvoyer un objet réponse qui implémente une méthode `render`. Elle peut modifier la réponse donnée en changeant `response.template_name` et `response.context_data`, ou elle peut créer et renvoyer une toute nouvelle classe [`TemplateResponse`](/fr/1.9/ref/template-response/#django.template.response.TemplateResponse) ou un équivalent.

Il n’est pas nécessaire d’effectuer explicitement le rendu des réponses, celles-ci étant automatiquement « rendues » après que tous les intergiciels de réponse ont été appelés.

Les intergiciels sont exécutés dans l’ordre inverse lors de la phase de réponse, ce qui inclut `process_template_response()`.

### `process_response()`

#### `process_response(request, response)`

`request` est un objet [`HttpRequest`](/fr/1.9/ref/request-response/#django.http.HttpRequest). `response` est l’objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse) ou [`StreamingHttpResponse`](/fr/1.9/ref/request-response/#django.http.StreamingHttpResponse) renvoyé par une vue Django ou par un intergiciel.

`process_response()` est appelée pour toutes les réponses avant qu’elles soient renvoyées au navigateur.

Elle doit renvoyer un objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse) ou [`StreamingHttpResponse`](/fr/1.9/ref/request-response/#django.http.StreamingHttpResponse). Elle peut modifier la réponse donnée ou elle peut créer et renvoyer une toute nouvelle instance de [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse) ou de [`StreamingHttpResponse`](/fr/1.9/ref/request-response/#django.http.StreamingHttpResponse).

Au contraire des méthodes `process_request()` et `process_view()`, la méthode `process_response()` est toujours appelée, même si les méthodes `process_request()` et `process_view()` de la même classe d’intergiciel ont été court-circuitées (parce qu’une méthode d’intergiciel précédente a renvoyé une réponse [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse)). En particulier,  ceci implique que votre méthode `process_response()` ne peut pas compter sur une configuration créée dans `process_request()`.

Pour terminer, rappelez-vous que durant la phase de réponse, les intergiciels sont appliqués dans l’ordre inverse, de bas en haut. Cela signifie que les classes définies à la fin de [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES) sont exécutées en premier.

#### Gestion des réponses en flux

Au contraire de [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse), [`StreamingHttpResponse`](/fr/1.9/ref/request-response/#django.http.StreamingHttpResponse) ne possède pas d’attribut `content`. En conséquence, les intergiciels ne peuvent plus compter sur le fait que toutes les réponses possèdent un attribut `content`. S’ils ont besoin d’accéder au contenu, ils doivent savoir s’ils ont affaire avec une réponse de type flux (streaming) et ajuster leur comportement en fonction de cela :

```
if response.streaming:
    response.streaming_content = wrap_streaming_content(response.streaming_content)
else:
    response.content = alter_content(response.content)
```

> **Note**
>
> Il faut toujours partir du principe que `streaming_content` est trop volumineux pour être stocké en mémoire. Les intergiciels de réponse peuvent l’adapter dans un nouveau générateur, mais ils ne devraient pas le consommer. L’adaptation s’implémente typiquement de cette façon :
>
> ```
> def wrap_streaming_content(content):
>     for chunk in content:
>         yield alter_content(chunk)
> ```

### `process_exception()`

#### `process_exception(request, exception)`

`request` est un objet [`HttpRequest`](/fr/1.9/ref/request-response/#django.http.HttpRequest). `exception` est un objet `Exception` généré par la fonction de vue.

Django appelle `process_exception()` lorsqu’une vue génère une exception. `process_exception()` doit renvoyer `None` ou un objet [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse). Si elle renvoie un objet  [`HttpResponse`](/fr/1.9/ref/request-response/#django.http.HttpResponse), les intergiciels de réponse par gabarit et de réponse sont appliqués, et la réponse résultante sera renvoyée au navigateur. Sinon, la gestion par défaut des exceptions intervient.

Encore une fois, les intergiciels sont exécutés dans l’ordre inverse lors de la phase de réponse, ce qui comprend `process_exception`. Si un intergiciel d’exception renvoie une réponse, les classes d’intergiciels situées au-dessus ne seront pas du tout appelées.

### `__init__()`

La plupart des classes d’intergiciels ne nécessitent pas d’initialisation dans la mesure où elles sont essentiellement des conteneurs pour les méthodes `process_*`. Si vous avez besoin d’une notion d’état global, il est possible d’utiliser `__init__` pour cela. Cependant, gardez à l’esprit ces restrictions :

- Django initialise les intergiciels sans paramètre, il n’est donc pas possible de définir des paramètres obligatoires à `__init__`.
- Contrairement aux méthodes `process_*` qui sont appelées une fois par requête, `__init__` n’est appelée qu”*une seule fois*, lorsque le serveur Web répond à la première requête.

#### Signalement d’un intergiciel à exclure

Il est parfois utile de déterminer au moment de l’exécution si un intergiciel doit être utilisé. Dans ces cas, la méthode `__init__` de l’intergiciel peut générer l’exception `django.core.exceptions.MiddlewareNotUsed`. Django se charge alors d’enlever cet intergiciel du processus des intergiciels et un message de débogage est journalisé vers `django.request` lorsque  [`DEBUG`](/fr/1.9/ref/settings/#std-setting-DEBUG) est défini à `True`.

> **Changed in Django 1.8**
>
> Précédemment, les exceptions [`MiddlewareNotUsed`](/fr/1.9/ref/exceptions/#django.core.exceptions.MiddlewareNotUsed) n’étaient pas journalisées.

### Lignes de conduite

- Les classes d’intergiciels n’ont aucune obligation d’héritage.
- Une classe d’intergiciel peut se trouver n’importe où dans le chemin Python. Tout ce que Django demande, c’est que le réglage [`MIDDLEWARE_CLASSES`](/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES) contienne le chemin de l’intergiciel.
- N’hésitez pas à examiner les [intergiciels disponibles dans Django](/fr/1.9/ref/middleware/) pour avoir des exemples.
- Si vous écrivez un composant intergiciel que vous pensez susceptible d’être utilisé par d’autres personnes, contribuez à la communauté ! [Faites-le nous savoir](/fr/1.9/internals/contributing/) et nous considérerons son éventuel ajout dans Django.
