Vous savez qu’il y a un settings qui ressemble à ça:
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ) |
Vous savez qu’il est important. Vous ne savez pas vraiment pourquoi.
WaT iZ a MideulWaire ?
Un middleware est un moyen d’éxécuter du code à toutes requêtes et/ou à toutes les réponses reçues et envoyées par Django. Si vous ne voyez pas comment fonctionne le cyle de requêtes/réponses, faites un petit saut sur notre schéma de fonctionnement général de Django.
Un middleware, c’est une classe Python ordinaire, avec deux méthodes: une appelée pour les requêtes, une appelée pour les réponses.
L’exemple bidon habituel
class MideulWaireForEverReturnsTheRevenge3(object): # cette méthode sera appelée automatiquement pour chaque requête # et Django lui passera la requête en cours def process_request(self, request): print "Hey, une requête est arrivée !" # on est pas obligé de retourner quoi que ce soit # cette méthode sera appelée automatiquement pour chaque réponse # et Django lui passera la reponse en cours et la requete # à laquelle on répond def process_response(self, request, response): print "Hey, on a répondu a une requête !" # on DOIT retourner une réponse return response |
On met tout ça dans un fichier mon_projet/mon_app/middlewares.py, et on active le middleware en le rajoutant dans les settings:
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'mon_projet.mon_app.middlewares.MideulWaireForEverReturnsTheRevenge3' ) |
Et à chaque reload de page, dans l’affichage du terminal de dev, on a ça:
Et voici ce qui se passe dans le fonctionnement de Django: il trouve la liste des classes de middlewares, et pour chaque requête et réponse, il appelle les méthodes process_response
et process_request
de chaque middleware.
Les points les plus importants
Aucune méthode n’est obligatoire, vous pouvez créer un middleware avec uniquement l’une ou l’autre.
Si process_request
renvoit une réponse, tout s’arrête. Les process_request
des autres middlewares ne sont pas appelés, vos vues ne sont pas appelées, et c’est le cycle de réponse qui commence directement. Très utile si par exemple vous voulez faire une redirection brutale pour toutes les requêtes qui correspondent à un certain critère (par exemple rediriger vers un site mobile).
Les middlewares sont appelés dans leur ordre de déclaration dans MIDDLEWARE_CLASSES
pour chaque requête, et dans l’ordre inverse pour chaque réponse. Mettez donc votre middleware au bon endroit dans la file: inutile de mettre un middleware qui vérifie si un user a des droits avant le middleware d’authentification, puisque l’utilisateur n’est pas encore authentifié.
Un middleware peut posséder 3 autres méthodes également facultatives: process_view
(appelée juste avant l’appel de chaque vue, et et permettant de modifier l’instance de la vue elle-même), process_template_response
(appelée sur chaque instance implémentant une méthode render, et surtout utilisée pour injecter des données dans TemplateResponse) et process_exception
(appelée quand une vue lève une exception).
Pour quoi utiliser les middleware ?
Exemples de quelques middlewares qui viennent d’office avec Django:
- UpdateCacheMiddleware, FetchFromCacheMiddleware: ils cachent l’intégralité des pages.
- GZipMiddleware: retourne une réponse compressée si le browser le gère.
- LocaleMiddleware: set la langue que Djando doit utiliser, en fonction du navigateur.
- MessageMiddleware: gestion des “flash-messages”.
- SessionMiddleware: gestion des sessions.
- AuthenticationMiddleware: authentifier un utilisateur.
Il y en a beaucoup d’autres, et il y en a plein qui trainent sur internet. Mais bien entendu le plus chouette, c’est d’en faire un soi-même.
Par exemple, quand je développe (pas en prod, hien !), j’utilise souvent ce petit middleware que j’ai fait avec amour:
class ForceSuperUserMiddleWare(object): def process_request(self, request): request.user = User.objects.filter(is_superuser=True)[0] |
Comme ça je suis toujours connecté en tant que super user, même sur les projets avec des timeout courts pour la session, des doubles authentifications super relous et tout le toutim des clients paranos (traduction: des américains).
Ordinaire avec un seul “N”
bonjour,
celle là m’a échappée :-) moins écorchée l’oeil aussi :)
Thx
Merci les gars, grace à vous on garde un semblant de crédibilité.
“et dans l’odre inverse “
Fixed.
Merci, super article
Merci pour cet excellent article, clair et très précis.