Middleware Django
Le middleware Django est un hook permettant de modifier les objets de requête ou de réponse de Django ; il peut être compris comme une étape de traitement entre la gestion de HttpRequest et celle de HttpResponse.
Pendant le processus allant de la requête à la réponse dans le navigateur, Django doit le gérer à travers de nombreux composants middleware, comme le montre la figure suivante :

Objectif du middleware Django :
- Modifier la requête, c'est-à-dire l'objet HttpRequest transmis à la vue.
- Modifier la réponse, c'est-à-dire l'objet HttpResponse renvoyé par la vue.
Les composants middleware sont configurés dans la liste d'options MIDDLEWARE du fichier settings.py.
Chaque option de type chaîne dans la configuration est une classe, c'est-à-dire un middleware.Configuration middleware par défaut de Django :
'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',
]
Middleware personnalisé
Un middleware peut définir quatre méthodes, à savoir :
process_view(self, request, view_func, view_args, view_kwargs)
process_exception(self, request, exception)
process_response(self, request, response)
Étapes pour personnaliser un middleware :
Créez un nouveau fichier py dans le répertoire de l’application avec un nom personnalisé, et importez MiddlewareMixin dans ce fichier py :
from django.utils.deprecation import MiddlewareMixin

Une classe middleware personnalisée doit hériter de la classe parente MiddlewareMixin :
class MD1(MiddlewareMixin):
pass
Enregistrez la classe middleware personnalisée dans MIDDLEWARE dans settings.py :'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',
'app01.middlewares.MD1',
]
Méthodes des classes middleware personnalisées
Les méthodes d’une classe middleware personnalisée incluent : process_request et process_response.

méthode process_request
La méthode process_request possède un paramètre, request, qui est le même que le request dans la fonction de vue.
La valeur de retour de la méthode process_request peut être soit None, soit un objet HttpResponse.
- Si la valeur de retour est None, poursuivez le flux normal et transmettez-le au middleware suivant pour traitement.
- Si la valeur de retour est un objet HttpResponse, Django n'exécutera pas les méthodes situées avant la fonction de vue suivante ni la fonction de vue elle-même. Au lieu de cela, à partir de ce middleware, il exécutera les middlewares dans l'ordre inverse, et n'exécutera que les méthodes qui s'exécutent après la fonction de vue.
La méthode process_request est exécutée avant la fonction de vue.
Lorsque plusieurs middlewares sont configurés, ils s'exécutent dans l'ordre selon l'ordre d'enregistrement dans MIDDLEWARE, c'est-à-dire la valeur d'index de la liste.
Le paramètre request transmis entre différents composants middleware est le même objet request.
Exemple
from django.shortcuts import render, HttpResponse
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request method.", id(request)) # Exécuté avant la vue

process_response
La méthode process_response a deux paramètres : l'un est request, et l'autre est response. request est l'objet de requête, et response est l'objet HttpResponse renvoyé par la fonction de vue. Cette méthode doit avoir une valeur de retour, et ce doit être response.
La méthode process_response est exécutée après la fonction de vue.
Lorsque plusieurs middlewares sont configurés, ils s'exécutent dans l'ordre inverse selon l'ordre d'enregistrement dans MIDDLEWARE, c'est-à-dire la valeur d'index de la liste.
Exemple
def process_request(self, request):
print("md1 process_request method.", id(request)) # Exécuté avant la vue
def process_response(self,request, response): :# Basé sur request/response
print("md1 process_response method!", id(request)) # Après la vue
return response
D'après la figure ci-dessous, dans des circonstances normales, l'exécution suit la route verte. Supposons queMiddleware 1s'il y a une valeur de retour, il suit la route rouge, exécute directement la méthode process_response de cette classe et retourne ; les autres middlewares suivants ne seront pas exécutés.

process_view
Le format de la méthode process_view est le suivant :
process_view(request, view_func, view_args, view_kwargs)La méthode process_view a quatre paramètres :
- request est un objet HttpRequest.
- view_func est la fonction de vue que Django est sur le point d'utiliser.
- view_args est la liste des arguments positionnels à transmettre à la vue.
- view_kwargs est le dictionnaire des arguments nommés à transmettre à la vue.
view_args et view_kwargs n'incluent pas le premier paramètre de la vue (request).
La méthode process_view est exécutée avant la fonction de vue et après la méthode process_request.
La valeur de retour peut être None, view_func(request), ou un objet HttpResponse.
- Si la valeur de retour est None, poursuivez le flux normal et transmettez-le au middleware suivant pour traitement.
- Si la valeur de retour est un objet HttpResponse, Django n'exécutera pas les méthodes situées avant la fonction de vue suivante ni la fonction de vue elle-même. Au lieu de cela, à partir de ce middleware, il exécutera les middlewares dans l'ordre inverse, et n'exécutera que les méthodes qui s'exécutent après la fonction de vue.
- c. Si la valeur de retour est view_func(request), Django n'exécutera pas les méthodes précédant les fonctions de vue suivantes, mais exécutera la fonction de vue à l'avance, puis exécutera les méthodes après la fonction de vue dans l'ordre inverse.
-
Une fois que le process_request du dernier middleware atteint le mappage de route, il revient au process_view du premier middleware, puis redescend dans l'ordre jusqu'à atteindre la fonction de vue.
Exemple
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request method.", id(request)) # Exécuté avant la vue
def process_response(self,request, response): :# Basé sur request/response
print("md1 process_response method!", id(request)) # Après la vue
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print(md1 process_view method!) # Exécuter avant la vue ; exécuter séquentiellement
#return view_func(request)


process_exception
La méthode process_exception est la suivante :
process_exception(request, exception)
Description du paramètre :
- request est un objet HttpRequest.
- exception est l'objet Exception généré par une exception dans la fonction de vue.
La méthode process_exception n'est exécutée que lorsqu'une exception se produit dans la fonction de vue, et elle s'exécute dans l'ordre inverse de l'enregistrement dans settings.
Exécutée après la fonction de vue et avant la méthode process_response.
La valeur de retour de la méthode process_exception peut être soit None, soit un objet HttpResponse.
Si la valeur de retour est None, la page signalera une erreur de code d'état 500, et la fonction de vue ne sera pas exécutée.
La méthode process_exception s'exécute dans l'ordre inverse, puis la méthode process_response s'exécute dans l'ordre inverse.
Si la valeur de retour est un objet HttpResponse, la page ne signalera pas d'erreur, et le code d'état de retour sera 200.
La fonction de vue n'est pas exécutée, et les méthodes process_exception suivantes de ce middleware ne sont pas non plus exécutées. L'exécution commence directement à partir de la méthode process_response du dernier middleware dans l'ordre inverse.
Si la méthode process_view renvoie la fonction de vue et que la fonction de vue est exécutée à l'avance, et que la fonction de vue signale une erreur, alors quelle que soit la valeur de retour de la méthode process_exception, la page signalera une erreur, et ni la fonction de vue ni la méthode process_exception ne seront exécutées.
Commencez directement l'exécution dans l'ordre inverse à partir de la méthode process_response du dernier middleware :
Exemple
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request method.", id(request)) # Exécuté avant la vue
def process_response(self,request, response): :# Basé sur request/response
print("md1 process_response method!", id(request)) # Après la vue
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print(md1 process_view method!) # Exécuter avant la vue ; exécuter séquentiellement
#return view_func(request)
def process_exception(self, request, exception):# Cette méthode est déclenchée uniquement lorsqu'une erreur est levée
print(md1 process_exception méthode!)
# return HttpResponse(exception) # Renvoyer le message d'erreur
autres extensions