The middleware
This is the 14th day of my participation in Gwen Challenge
A. The request is sent to WSGI, which encapsulates the request data (request) b. Django matches the path and determines which function to execute based on the path C. D. The function returns a response, and Django returns it in the format of an HTTP responseCopy the code
Djangos middleware is a framework level hook that handles Django requests and responses on a global scale. The framework level hooks in Django that handle requests and their corresponding frameworks are essentially a class that defines five methods that are executed at specific times.Copy the code
Settings. py is 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',]Copy the code
Django request lifecycle
Creating middleware
1. Create a new folder under app01, Middlewares 2. In the folder, define the middleware class my_middlewares.py 3. When writing middleware, be sure to inherit MiddlewareMixinCopy the code
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MD1(MiddlewareMixin) :
def process_request(self,request) :
print(id(request))
print("MD1 request")
return HttpResponse("If there is a return value in the middle key, the view function behind it is not executed, not even after the middle key.")
Copy the code
4. Register to define MIDDLEWARE in settings.pyCopy the code
MIDDLEWARE = [
'app01.Middlewares.My_Middlewares.MD1',
# 'app01.Middlewares.My_Middlewares.MD2',
]
Copy the code
Five methods, four features
Execution Time Execution order Parameter Returned value
process_request
Process_request (self, request) # Process_request (self, request) # process_request(self, request) # process_request(self, request) # None Normal process HttpResponse does not execute the following view functions, route matching, or even the intermediate key, and returns directly to the browser to execute the process_response method of the current middlewareCopy the code
process_response
Order of execution: the arguments are executed in the order in which they were registered and the arguments are executed in reverse order when process_response is returned: Request The request object and the view function are the same object. Response The return value of the response object: HttpResponse must be returnedCopy the code
process_view
Process_view (self,request,view_func,view_args,view_kwargs) # process_view(self,request,view_func,view_args,view_kwargs) # The process_view method is executed after process_request and before the view function in the order in which it was registered: Request The requested object and view function are the same object view_func view function view_args Position argument of the view function () tuple view_kwargs Keyword argument of the view function {} dictionary Return value: None Normal process HttpResponse 1. If process_response contains a return response, the middleware's process_view method is returned. None of the view functions executes 2. If process_response is a return HttpResponse, execute the process_response method of the last middlewareCopy the code
process_exception
Process_exception (self, request, exception) process_exception(self, request, exception) # Process_exception (self, request, exception) Request The request object and the view function are the same object. Exception HttpResponse the middleware handled the exception, and the middleware process_Exception will not execute. Execute the process_response method of the last middlewareCopy the code
process_template_response
Process_template_response (self, request, response) # Process_template_response (self, request, response) Request The requested object and the view function are the same object. Response The TemplateResponse object returned the value: HttpResponse TemplateResponse object procedure template name parameter response.template_name response.context_dataCopy the code
Process_template_response is executed immediately after the view function completes, but only if the object returned by the view function has a render() method (or indicating that the object is a TemplateResponse object or its equivalent)
Custom middleware
Middleware, as its name suggests, is a intermediate process between request and response processing that is relatively lightweight and changes Django’s input and output globally
Instance of a
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MD1(MiddlewareMixin) :
def process_request(self, request) :
print("MD1 process_request")
# ret = HttpResponse(" If there is a return value inside the middle key, the following view function is not executed, even after the middle key ")
# return ret
def process_response(self, request, response) :
print("MD1 process_response")
return response
def process_view(self, request, view_func, view_args, view_kwargs) :
# print(request) #
# print(view_func) #
# print(view_args) # ('1',)
# print(view_kwargs) # {'id': '2'}
print("MD1 process_view")
# return HttpResponse("MD1 process_view")
def process_exception(self,request,exception) : The view function is executed only when there is an exception
print("Abnormal")
def process_template_response(self,request,response) :
print("MD1 process_template_response")
return response
Copy the code
The view function
from django.shortcuts import render, HttpResponse
from django.template.response import TemplateResponse
# Create your views here.
def index(request,*args,**kwargs) :
print("index")
# return render(request,"index.html",{"user":"abcdefg"})
return TemplateResponse(request,"index.html", {"user":"abcdefg"})
Copy the code
Example 2
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MD1(MiddlewareMixin) :
def process_request(self, request) : You must define a method with this name, and the parameter must be written
print('MD1 request is coming in ')
print(request.path) Request path
if request.path == '/xx/':
return None
else:
return HttpResponse('There's something wrong with you. You can't go! ') # The ones behind don't go
# return None # Return None
def process_response(self, request, response) : You must define a method with this name, and two parameters must also be written
print('MD1 response is coming. ')
return response Response must be returned
class MD2(MiddlewareMixin) :
def process_request(self, request) : This method must be defined
print('MD2 request is coming in ')
def process_response(self, request, response) :
print('MD2 response is coming. ')
return response
# settins file
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
'app01.utils.mymiddleware.MD1'.'app01.utils.mymiddleware.MD2',]# outputMD1 request coming /xx/ MD2 request coming MD2 response coming MD1 response coming [20/Nov/2020 09:33:28] "GET /xx/ HTTP/1.1" 200 2MD1 request coming /login/ MD1 response coming [20/Nov/2020 09:33:37] "The GET/login/HTTP / 1.1" 200 33
Copy the code
Middleware exercises
The access frequency is limited to three times in five seconds
## 1. Set up middleware
Method a #
Print (request.path_info) # print(request.meta) # print(request.meta) #
visit_history = { # Historical time
# ip:[time,time]
}
print(visit_history)
class Thorttle(MiddlewareMixin) :
def process_request(self, request) :
ip = request.META['REMOTE_ADDR'] # 127.0.0.1
history = visit_history.get(ip, []) # set parameters {'127.0.0.1': []}
print("history:", history)
# first history []
# Second History [1597467450]
# 3rd history [1597467450,1597467451]
# 4th history [1597467450,1597467451,1597467453]
now = time.time()
new_history = [] # Loop it once, leaving it empty
for i in history:
if now - i < 5: If the new time minus the old time is less than 5 seconds, add it to new_history
new_history.append(i)
visit_history[ip] = new_history
print(visit_history)
if (len(new_history)) >= 3:
return HttpResponse("Please wait for an interview.")
new_history.append(now)
Method # 2
visit_history = { # Historical time
# ip:[time,time]
}
class Thorttle(MiddlewareMixin) :
def process_request(self, request) :
ip = request.META['REMOTE_ADDR'] # 127.0.0.1
history = visit_history.get(ip, []) # set parameters {'127.0.0.1': []}
now = time.time()
while history and now-history[-1] >5:
history.pop()
if (len(history)) >= 3:
return HttpResponse("Please wait for an interview.")
history.append(now)
visit_history[ip] = history
Copy the code
- Add it in settings.py
MIDDLEWARE = [ 'app01.Middlewares.My_Middlewares.Thorttle',]
Copy the code
Whitelist of middleware authentication
Instead of decorators in the form of middleware,
# mymiddleware.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect
from django.urls import reverse
Middleware certification
class SessionAuth(MiddlewareMixin) :
def process_request(self, request) :
# white list
print(request.path)
white_list = [reverse('login'),]Add the whitelist to the list if you want it to pass. The whitelist is stored in the Settings file, and then referenced in the Settings file
print(white_list)
if request.path in white_list:
return None
is_login = request.session.get('is_login') # the session authentication
if is_login:
return None
else:
return redirect('login')
# settins
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
# 'app01.utils.mymiddleware.MD1',
# 'app01.utils.mymiddleware.MD2',
'app01.utils.mymiddleware.SessionAuth',]# views.py
def login(request) :
if request.method == 'GET':
return render(request, 'login.html')
else:
name = request.POST.get('name')
pwd = request.POST.get('pwd')
print(name, pwd)
if name == 'laowang' and pwd == '123':
# ret = redirect('/home/')
# ret.set_cookie('is_login', 0)
# return ret
request.session['is_login'] = True
request.session['username'] = 'bo'
Session_id is generated
# 2. Add a key-value pair to the cookie
# 3. Save to the django.session table
return redirect('/home/')
else:
return redirect('login')
def logout(request) :
request.session.flush() Clear all cookies and sessions
return redirect("/login/")
def home(request) :
return render(request, 'home.html')
def index(request) :
return render(request, 'index.html')
Copy the code
Attached: Django request flowchart
conclusion
The article is long, give a big thumbs up to those who see it! Due to the author’s limited level, the article will inevitably have mistakes, welcome friends feedback correction.
If you find this article helpful, please like, comment, and bookmark it
Your support is my biggest motivation!!