Django-fr | Documentation | Middleware

Django-fr

Documentation Django

Middleware

Middleware est un système de branchement au processus requête/réponse de Django. C'est un système de "plugin" léger et de bas niveau pour modifier globalement les entrées et/ou les sorties de Django.

Chaque composant du middleware est responsable d'une fonction spécifique. Par exemple, Django fournit le composant middleware XViewMiddleware, qui ajoute un en-tête HTTP "X-View" à chaque réponse à une requête HEAD.

Ce document détaille tous les composants middleware fournis avec Django, comment les utiliser, et comment écrire votre propre middleware.

Activer le middleware

Pour activer un composant middleware, ajoutez-le à la liste MIDDLEWARE_CLASSES dans vos réglages Django (settings.py). Dans la liste MIDDLEWARE_CLASSES, chaque composant est représenté par une chaîne de caractères : le chemin Python complet vers le nom de la classe du middleware. Par exemple, voici la liste MIDDLEWARE_CLASSES créée par défaut par django-admin.py startproject:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.doc.XViewMiddleware',
)

Django applique les middlewares dans l'ordre où ils sont définis dans MIDDLEWARE_CLASSES, excepté dans les cas de middleware de réponse et d'exception, qui sont appliqués dans l'ordre inverse.

Une installation Django ne nécessite aucun middleware -- c'est-à-dire que MIDDLEWARE_CLASSES peut être vide si vous le souhaitez -- mais il est fortement recommandé d'utiliser CommonMiddleware.

Middlewares disponibles

django.middleware.cache.CacheMiddleware

Active le système de cache pour le site. S'il est activé, chaque page rendue par Django sera cachée pour une durée égale au réglage CACHE_MIDDLEWARE_SECONDS. Voir la documentation du cache.

django.middleware.common.CommonMiddleware

Ajoute quelques aménagements pour les perfectionnistes :

  • Interdit l'accès aux "user agents" présents dans le réglage DISALLOWED_USER_AGENTS, qui doit être une liste de chaînes de caractères.

  • Procède aux réécritures d'URL en fonction des réglages APPEND_SLASH et PREPEND_WWW.

    Si APPEND_SLASH est True, que l'URL d'origine ne se termine pas par un slash et qu'elle n'est pas trouvée dans l'URLconf, une nouvelle URL est formée en ajoutant un slash à la fin. Si cette nouvelle URL est trouvée dans l'URLconf, Django redirige la requête vers cette nouvelle URL. Sinon l'URL d'origine est traitée comme d'habitude.

    Par exemple, foo.com/bar sera redirigée vers foo.com/bar/ si vous n'avez pas de modèle d'URL valide pour foo.com/bar et en avez un valide pour foo.com/bar/.

    Nouveau dans la version de développement de Django : le comportement de APPEND_SLASH a légèrement changé dans la version de développement. Avant, on ne vérifiait pas si l'URL avait une correspondance dans les modèles de URLconf.

    Si PREPEND_WWW est True, les URL auxquelles manque le préfixe "www." seront redirigées vers la même URL avec le préfixe manquant.

    Ces deux options sont supposées normaliser les URLs. La philosophie est que chaque URL ne devrait exister qu'à un et un seul endroit. Techniquement, une URL foo.com/bar est distincte de foo.com/bar/ -- un moteur de recherche les indexerait comme deux URL séparées -- donc il est préférable de normaliser les URLs.

  • Gère les ETags en fonction du réglage USE_ETAGS. Si USE_ETAGS est positionné à True, Django calculera un ETag pour chaque requête en calculant la somme MD5 du contenu de la page, et s'occupera de renvoyer la réponse Not Modified si nécessaire.

django.middleware.doc.XViewMiddleware

Envoie un en-tête HTTP X-View adapté aux requêtes HEAD qui viennent d'adresses IP définies dans le réglage INTERNAL_IPS. Utilisé par le système de documentation automatique de Django.

django.middleware.gzip.GZipMiddleware

Compresse le contenu pour les navigateurs qui savent gérer la compression gzip (tous les navigateurs modernes).

Il est préférable de placer ce middleware en premier dans la liste, de façon que la compression du contenu de la réponse soit la dernière chose qui arrive (avant l'envoi de celle-ci). Les contenus de moins de 200 octets, les réponses dont le code est différent de 200, les fichiers Javascript (pour la compatibilité avec IE) et les réponses dont le header Content-Encoding est déjà spécifié ne seront pas compressés.

django.middleware.http.ConditionalGetMiddleware

Gère les opérations GET conditionnelles. Si la réponse a un en-tête ETag ou Last-Modified et la requête a If-None-Match ou If-Modified-Since, la réponse est remplacée par un HttpNotModified.

Positionne également les en-têtes de réponse Date et Content-Length.

django.middleware.http.SetRemoteAddrFromForwardedFor

Renseigne request.META['REMOTE_ADDR'] en fonction de request.META['HTTP_X_FORWARDED_FOR'], si cette dernière valeur existe. Utile si vous êtes derrière un reverse proxy qui donne à chaque requête REMOTE_ADDR la valeur 127.0.0.1.

Note importante : Ceci ne valide PAS HTTP_X_FORWARDED_FOR. Si vous n'êtes pas derrière un proxy reverse qui renseigne HTTP_X_FORWARDED_FOR automatiquement, n'utilisez pas ce middleware. N'importe qui peut truquer la valeur de HTTP_X_FORWARDED_FOR, et parce que ce middleware renseigne REMOTE_ADDR sur la base de HTTP_X_FORWARDED_FOR, ça signifie que n'importe qui peut "falsifier" son adresse IP. N'utilisez ce middleware que si vous êtes absolument certain de la validité de HTTP_X_FORWARDED_FOR.

django.middleware.locale.LocaleMiddleware

Active le choix de la langue en fonction des données fournies dans la requête. Cela permet de personnaliser le contenu pour chaque utilisateur. Voir la documentation de l'internationalisation.

django.contrib.sessions.middleware.SessionMiddleware

Active le support des sessions. Voir la documentation des sessions.

django.contrib.auth.middleware.AuthenticationMiddleware

Ajoute l'attribut user représentant l'utilisateur actuellement authentifié à chaque objet HttpRequest entrant. Voir Authentification dans les requêtes Web.

django.contrib.csrf.middleware.CsrfMiddleware

Nouveau dans la version de développement de Django

Fournit une protection contre les Cross Site Request Forgeries en ajoutant un champ caché aux formulaires POST et en vérifiant qu'une valeur correcte est envoyée dans la requête. Voir la documentation de la protection contre les Cross Site Request Forgeries.

django.middleware.transaction.TransactionMiddleware

Associe "commit" et "rollback" à la phase de requête/réponse. Si une vue fonctionne avec succès, le commit est réalisé. Si elle échoue avec une levée d'exception, un rollback est réalisé.

Le rang de ce middleware dans la pile est important : les modules de middleware qui sont placés avant celui-ci auront le fonctionnement par défaut de Django qui est commit et sauvegarde. Les modules de middleware placés après celui-ci dans la pile seront sous son contrôle et donc fonctionneront comme expliqué pour les vues ci-dessus.

Voir la documentation des transactions.

Écrire votre propre middleware

Écrire votre propre middleware est facile. Chaque composant de middleware est une simple classe Python qui définit une ou plus des méthodes suivantes :

process_request

Interface: process_request(self, request)

request est un objet HttpRequest. Cette méthode est appelée à chaque requête , avant que Django ne décide quelle vue exécuter.

process_request() doit renvoyer soit None, soit un objet HttpResponse. Si la valeur renvoyée est None, Django continuera à traiter la requête, en exécutant les autres middlewares de la pile, puis la vue appropriée. Si la valeur renvoyée est un objet HttpResponse, Django n'appellera plus AUCUN autre middleware de requête, de vue ou d'exception, ou la vue appropriée, il renverra cet objet HttpResponse. Le middleware de réponse est toujours appelé sur chaque réponse.

process_view

Interface: process_view(self, request, view_func, view_args, view_kwargs)

request est un objet HttpRequest. view_func est la fonction Python que Django est sur le point d'utiliser (c'est l'objet fonction lui-même, pas son nom passé en chaîne de caractères). view_args est une liste de paramètres positionnels qui sera passée à la vue, et view_kwargs est un dictionnaire de paramètres nommés qui sera passé à la vue. Ni view_args, ni view_kwargs ne contiennent le premier paramètre (request).

process_view() est appelé juste avant que Django n'appelle la vue. Doit renvoyer soit None, soit un objet HttpResponse. Si la valeur renvoyée est None, Django continuera à traiter la requête, en exécutant tous les autres middleware process_view(), puis la vue appropriée. Si la valeur renvoyée est un objet HttpResponse, Django n'appellera plus AUCUN middleware de requête, de vue ou d'exception, ni la vue appropriée : il renverra simplement cet objet HttpResponse. Le middleware de réponse est toujours appelé sur chaque réponse.

process_response

Interface: process_response(self, request, response)

request est un objet HttpRequest. response est l'objet HttpResponse renvoyé par une vue Django.

process_response() doit renvoyer un objet HttpResponse. Il peut modifier la response fournie, ou créer et renvoyer un objet HttpResponse complètement nouveau.

process_exception

Interface: process_exception(self, request, exception)

request est un objet HttpRequest. exception est un objet Exception levé par la vue.

Django appelle process_exception() quand une vue lève une exception. process_exception() doit renvoyer soit None, soit un objet HttpResponse. S'il renvoie un objet HttpResponse, celui-ci sera renvoyé au navigateur client. Sinon, la gestion par défaut des exceptions prend le relais.

Indications

  • Les classes middleware ne doivent pas subclasser quoi que ce soit.
  • Les classes middleware peuvent se trouver où vous voulez dans votre chemin de recherche Python. La seule chose qui importe à Django, c'est que le réglage MIDDLEWARE_CLASSES indique le chemin vers celles-ci.
  • N'hésitez pas à jeter un oeil aux middleware fournis par Django pour avoir des exemples. Les classes de base des middleware Django sont dans django/middleware/ dans la distribution Django. Les middleware des sessions sont dans django/contrib/sessions.
  • Si vous écrivez un composant middleware que vous pensez pouvoir être utile aux autres, contribuez à la communauté ! Faites-le nous savoir, et nous regarderons s'il peut être ajouté à Django.