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
  1. 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!!