Django Middleware
Django middleware is a hook for modifying Django request or response objects. It can be understood as a processing step between HttpRequest and HttpResponse processing.
During the process from browser request to response, Django needs to process through many middleware. As shown in the following image:
!(#)
Django middleware functions:
* Modify request, i.e., the HttpRequest object passed to the view.
* Modify response, i.e., the HttpResponse object returned by the view.
Middleware components are configured in the MIDDLEWARE option list in the settings.py file.
Each string option in the configuration is a class, which is a middleware.
Django's default middleware configuration:
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',
]
### Custom Middleware
Middleware can define four methods, respectively:
process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_exception(self, request, exception)
process_response(self, request, response)
Steps to create custom middleware:
Create a new py file in the app directory with a custom name, and import MiddlewareMixin in that py file:
from django.utils.deprecation import MiddlewareMixin
!(#)
The custom middleware class must inherit from the parent class MiddlewareMixin:
class MD1(MiddlewareMixin): pass
Register the custom middleware class in MIDDLEWARE in settings.py:
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',
'app01.middlewares.MD1',
]
* * *
## Custom Middleware Class Methods
The custom middleware class methods are: process_request and process_response.
!(#)
### process_request Method
The process_request method has one parameter request, which is the same as the request in the view function.
The return value of process_request method can be None or an HttpResponse object.
* If the return value is None, the normal process continues and is passed to the next middleware for processing.
* If the return value is an HttpResponse object, Django will not execute subsequent methods before the view function or the view function. Instead, it will start from this middleware in reverse order to execute middleware, and execute the methods that are supposed to run after the view function.
The process_request method is executed before the view function.
When multiple middleware are configured, they are executed in order according to the registration order in MIDDLEWARE, which is the list index value.
The request parameter passed between different middlewares is the same request object.
## Example
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request method.",id(request))#Execute before view
!(#)
### process_response
The process_response method has two parameters, one is request and the other is response. Request is the request object, and response is the HttpResponse object returned by the view function. This method must have a return value, and it must be response.
The process_response method is executed after the view function.
When multiple middleware are configured, they are executed in reverse order according to the registration order in MIDDLEWARE, which is the list index value.
## Example
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request method.",id(request))#Execute before view
def process_response(self,request, response): :#Based on request and response
print("md1 process_response method!",id(request))#Execute after view
return response
From the image below, under normal circumstances, it executes according to the green route. Assuming **Middleware1** has a return value, it follows the red route and directly executes the process_response method of that class to return, and subsequent middleware will not be executed.
!(#)
### process_view
The process_view method format is as follows:
process_view(request, view_func, view_args, view_kwargs)
The process_view method has four parameters:
* request is the HttpRequest object.
* view_func is the view function that Django is about to use.
* view_args is the list of positional arguments to be passed to the view.
* view_kwargs is the dictionary of keyword arguments to be passed to the view.
view_args and view_kwargs do not include the first view parameter (request).
The process_view method is executed before the view function, after the process_request method.
The return value can be None, view_func(request) or an HttpResponse object.
* If the return value is None, the normal process continues and is passed to the next middleware for processing.
* If the return value is an HttpResponse object, Django will not execute subsequent methods before the view function or the view function. Instead, it will start from this middleware in reverse order to execute middleware, and execute the methods that are supposed to run after the view function.
* c. If the return value is view_func(request), Django will not execute subsequent methods before the view function, but will execute the view function in advance, and then execute the methods after the view function in reverse order.
* When the last middleware's process_request reaches the route mapping, it returns to the first middleware's process_view, and then proceeds in order to reach the view function.
## Example
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request method.",id(request))#Execute before view
def process_response(self,request, response): :#Based on request and response
print("md1 process_response method!",id(request))#Execute after view
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print("md1 process_view method!")#Execute before view, execute in order
#return view_func(request)
!(#)
!(#)
### process_exception
The process_exception method is as follows:
process_exception(request, exception)
Parameter description:
*
YouTip