---
title: "Intergiciels (« Middleware »)"
version: 1.10
locale: fr
source: https://docs.djangoproject.com/fr/1.10/topics/http/middleware/
canonical: https://djangodocs.dev/fr/1.10/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.10/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.10/ref/middleware/).

> **Changed in Django 1.10**
>
> Un nouveau style d’intergiciel a été introduit conjointement au nouveau réglage [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE) setting. Si vous utilisez l’ancien réglage [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES), il sera nécessaire [d’adapter les anciens intergiciels personnalisés](#upgrading-middleware) avant d’utiliser le nouveau réglage. Ce document présente les intergiciels de nouvelle génération. Référez-vous à cette même page dans d’anciennes versions de la documentation pour trouver une description du fonctionnement des intergiciels précédents.

## Écriture de son propre intergiciel

Une fabrique d’intergiciel est un objet exécutable acceptant un exécutable `get_response` et renvoyant un intergiciel. Un intergiciel est un objet exécutable acceptant une requête et renvoyant une réponse, tout comme une vue.

Un intergiciel peut être écrit comme une fonction qui ressemble à ceci :

```
def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware
```

Ou il peut être écrit comme une classe dont les instances peuvent être appelées, comme ceci :

```
class SimpleMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response
```

L’exécutable `get_response` fournit par Django pourrait être la vue elle-même (s’il s’agit du dernier intergiciel) ou alors le prochain intergiciel dans la chaîne. L’intergiciel actuel n’a pas besoin de savoir ou de se préoccuper de ce que c’est exactement, il lui suffit de savoir que ça représente ce qui vient ensuite.

Nous avons un peu simplifié l’explication ci-dessus, car l’exécutable `get_response` du dernier intergiciel dans la chaîne est en fait une méthode enveloppant la vue, créée par le gestionnaire se chargeant d’appliquer les [intergiciels de vue](#view-middleware); cette méthode appelle la vue avec les paramètres appropriés et applique les intergiciels [template-response](#template-response-middleware) et [exception](#exception-middleware).

Les intergiciels peuvent se trouver n’importe où dans votre chemin Python.

### `__init__(get_response)`

Les fabriques d’intergiciel doivent accepter un paramètre `get_response`. Il est aussi possible d’initialiser de l’état global pour l’intergiciel. Gardez à l’esprit quelques précautions :

- Django initialise les intergiciels avec le seul paramètre `get_response`, il n’est donc pas possible de définir d’autres paramètres obligatoires à `__init__()`.
- Contrairement à la méthode `__call__()` qui est appelée une fois par requête, `__init__()` n’est appelée qu”*une seule fois*, lorsque le serveur Web démarre.

> **Changed in Django 1.10**
>
> Dans les anciennes versions, `__init__()` n’était pas appelée avant que le serveur Web ne réponde à sa première requête.
>
> Dans les anciennes versions, `__init__()` n’acceptait aucun paramètre. Pour permettre à votre intergiciel de fonctionner dans Django version 1.9 ou antérieure, faites de `get_response` un paramètre facultatif (`get_response=None`).

### Signalement d’un intergiciel à exclure

Il est parfois utile de déterminer au moment du démarrage 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 jouranlise un message de débogage vers le journaliseur [django.request](/fr/1.10/topics/logging/#django-request-logger) lorsque  [`DEBUG`](/fr/1.10/ref/settings/#std-setting-DEBUG) vaut `True`.

## Activation des intergiciels

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

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

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

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

L’ordre dans [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE) a son importance car un intergiciel peut dépendre d’un autre. Par exemple, [`AuthenticationMiddleware`](/fr/1.10/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.10/ref/middleware/#django.contrib.sessions.middleware.SessionMiddleware). Voir [Ordre des intergiciels](/fr/1.10/ref/middleware/#middleware-ordering) pour d’autres indications utiles concernant l’ordre des classes d’intergiciel de Django.

## Ordre des intergiciels et empilement

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`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE), de haut en bas.

Vous pouvez l’imaginer comme un oignon : chaque classe d’intergiciel est une « couche » qui enveloppe la vue, elle-même le cœur de l’oignon. Si la requête traverse toutes les couches de l’oignon (chacune appelant `get_response` pour passer la requête à la prochaine couche), jusqu’à atteindre la vue au cœur, la réponse va ensuite traverser elle-même toutes les couches (dans l’ordre inverse) jusqu’à sa sortie du mécanisme.

Si l’une des couches décide de court-circuiter et de renvoyer une réponse sans jamais appeler `get_response`, aucune des couches de l’oignon plus à l’intérieur de cette couche (y compris la vue) ne verra la requête ou la réponse. La réponse ne traversera toujours que les mêmes couches traversées par la requête.

## Autres points d’entrée d’intergiciel

En dehors du modèle basique requête/réponse d’intergiciel présenté précédemment, vous pouvez ajouter trois autres méthodes spéciales aux intergiciels basés sur des classes :

### `process_view()`

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

`request` est un objet [`HttpRequest`](/fr/1.10/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.10/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.10/ref/request-response/#django.http.HttpResponse), Django ne prend pas la peine d’appeler la vue correspondante ; il va simplement appliquer les intergiciels de réponse à cet objet [`HttpResponse`](/fr/1.10/ref/request-response/#django.http.HttpResponse) et renvoyer le résultat.

> **Note**
>
> L’accès à [`request.POST`](/fr/1.10/ref/request-response/#django.http.HttpRequest.POST) depuis un intergiciel avant que la vue ne soit exécutée ou dans `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.10/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly), et devrait donc être évité.
>
> La classe [`CsrfViewMiddleware`](/fr/1.10/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware) peut être considérée comme une exception, car elle fournit les décorateurs [`csrf_exempt()`](/fr/1.10/ref/csrf/#django.views.decorators.csrf.csrf_exempt) et [`csrf_protect()`](/fr/1.10/ref/csrf/#django.views.decorators.csrf.csrf_protect) qui permettent aux vues de contrôler explicitement le moment de la validation CSRF.

### `process_exception()`

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

`request` est un objet [`HttpRequest`](/fr/1.10/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.10/ref/request-response/#django.http.HttpResponse). Si elle renvoie un objet  [`HttpResponse`](/fr/1.10/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](/fr/1.10/ref/views/#error-views) 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 méthodes `process_exception` des classes d’intergiciels situées au-dessus ne seront pas du tout appelées.

### `process_template_response()`

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

`request` est un objet [`HttpRequest`](/fr/1.10/ref/request-response/#django.http.HttpRequest). `response` est l’objet [`TemplateResponse`](/fr/1.10/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.10/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.10/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()`.

## Gestion des réponses en flux

Au contraire de [`HttpResponse`](/fr/1.10/ref/request-response/#django.http.HttpResponse), [`StreamingHttpResponse`](/fr/1.10/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)
> ```

## Gestion des exceptions

Django convertit automatiquement les exceptions produites par la vue ou par l’intergiciel en une réponse HTTP appropriée avec un code de statut d’erreur. [Certaine exceptions](/fr/1.10/ref/views/#error-views) sont converties en codes de statut 4xx, alors qu’une exception inconnue est convertie en un code de statut 500.

Cette conversion a lieu avant et après chaque intergiciel (vous pouvez vous représenter cela comme la fine peau entre chaque couche de l’oignon), afin que chaque intergiciel puisse toujours compter sur l’obtention d’un certain type de réponse HTTP en retour de son appel à `get_response`. Les intergiciels n’ont pas besoin se se soucier d’envelopper leur appel à `get_response` dans un bloc `try/except` pour gérer une exception qui aurait pu être générée par un intergiciel suivant ou par la vue. Même si l’intergiciel suivant dans la chaîne génère une exception [`Http404`](/fr/1.10/topics/http/views/#django.http.Http404), par exemple, votre intergiciel ne verra pas cette exception ; il obtiendra à la place un objet [`HttpResponse`](/fr/1.10/ref/request-response/#django.http.HttpResponse) avec un code [`status_code`](/fr/1.10/ref/request-response/#django.http.HttpResponse.status_code) 404.

## Mise à jour d’intergiciels écrits avant Django 1.10

#### `class django.utils.deprecation.MiddlewareMixin`

Django fournit `django.utils.deprecation.MiddlewareMixin` pour faciliter la création de classes d’intergiciel qui sont compatibles à la fois avec [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE) et l’ancien [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES). Toutes les classes d’intergiciel incluses dans Django sont compatibles avec les deux réglages.

Cette classe « mixin » fournit une méthode `__init__()` acceptant un paramètre facultatif `get_response` et le stockant dans `self.get_response`.

La méthode `__call__()`:

1. Appelle `self.process_request(request)` (si elle est définie).
2. Appelle `self.get_response(request)` pour obtenir la réponse du dernier intergiciel et de la vue.
3. Appelle `self.process_response(request, response)` (si elle est définie).
4. Renvoie la réponse.

Quand elle est utilisée avec [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES), la méthode `__call__()` ne sera jamais utilisée ; Django appelle directement `process_request()` et `process_response()`.

Dans la plupart des cas, l’héritage de cette classe « mixin » suffit à rendre compatible un intergiciel ancien style avec le nouveau système avec suffisamment de rétro-compatibilité. La nouvelle sémantique de court-circuitage ne fera pas de mal ou sera même avantageuse pour l’intergiciel existant. Dans quelques cas, une classe d’intergiciel pourrait avoir besoin de certains changements pour s’ajuster à la nouvelle sémantique.

Voici les différences de comportement entre l’utilisation de [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE) et de [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES):

1. Avec [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES), chaque intergiciel verra toujours sa méthode `process_response` appelée, même si un intergiciel précédent a court-circuité le processus en renvoyant une réponse de sa méthode `process_request`. Avec [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE), les intergiciels se comportent plus comme un oignon : les couches que parcourt une réponse jusqu’à sa sortie sont les mêmes que la requête a vu passer dans le sens inverse. Si un intergiciel court-circuite, seul cet intergiciel et ceux qui le précèdent dans [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE) verront passer la réponse.
2. Avec [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES), `process_exception` est appliquée aux exceptions générées depuis une méthode `process_request` d’intergiciel. Avec [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE), `process_exception` ne s’applique qu’aux exceptions générées dans la vue (ou depuis la méthode `render` d’une réponse [`TemplateResponse`](/fr/1.10/ref/template-response/#django.template.response.TemplateResponse)). Les exceptions générées depuis un intergiciel sont converties en une réponse HTTP appropriée puis transmises à l’intergiciel suivant.
3. Avec [`MIDDLEWARE_CLASSES`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE_CLASSES), si une méthode `process_response` génère une exception, les méthodes `process_response` de tous les intergiciels précédents sont omises et une réponse HTTP `500 erreur de serveur interne` est toujours renvoyée (même si l’exception générée était par exemple [`Http404`](/fr/1.10/topics/http/views/#django.http.Http404)). Avec [`MIDDLEWARE`](/fr/1.10/ref/settings/#std-setting-MIDDLEWARE), une exception générée depuis un intergiciel est immédiatement convertie en une réponse HTTP appropriée, puis le prochain intergiciel dans la chaîne verra la réponse. Les intergiciels ne sont jamais outrepassés en raison d’une exception générée dans un autre intergiciel.
