django之(中间件)middleware

Posted alexephor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django之(中间件)middleware相关的知识,希望对你有一定的参考价值。

中间件

  django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

  在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件(内置) 

  详细:https://docs.djangoproject.com/en/2.2/ref/middleware/#security-middleware 

 

1 MIDDLEWARE = [
2     django.middleware.security.SecurityMiddleware,
3     django.contrib.sessions.middleware.SessionMiddleware,
4     django.middleware.common.CommonMiddleware,
5     django.middleware.csrf.CsrfViewMiddleware,
6     django.contrib.auth.middleware.AuthenticationMiddleware,
7     django.contrib.messages.middleware.MessageMiddleware,
8     django.middleware.clickjacking.XFrameOptionsMiddleware,
9 ]

  中间件中可以定义五个方法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

  以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

Django的请求生命周期如图:

技术图片

 自定义中间件

创建中间件类

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from django.shortcuts import HttpResponse
 5 from django.utils.deprecation import MiddlewareMixin
 6 
 7 
 8 class M1(MiddlewareMixin):
 9 
10     def process_request(self, request):
11         """
12         内部已经帮我们返回
13         如果我们自己加上返回值,在1.1版本前直接在当前中间件的process_response方法返回
14         在1.7 1.8版本后要跳到最后一个中间件的process_response方法一层层的返回
15         :param request:
16         :return:
17         """
18         print(m1.process_request)
19 
20     def process_view(self, request, callback, callback_args, callback_kwargs):
21         """
22         得到当前请求的执行视图函数名字
23         :param request:
24         :param callback:
25         :param callback_args:
26         :param callback_kwargs:
27         :return:
28         """
29         print(m1.process_view)
30         print(callback)
31         # 如果这里执行callback(就是视图函数的名字)函数,下面每一个中间件的process_view方法都不走了,直接返回执行视图函数的结果
32         # 如果这里不执行callback视图函数方法,那么继续走下面中间件的process_view,如果都没执行(这里又有加装饰器的作用了,\\
33         # 如果视图函数要加装饰器,那么这里加上装饰器)再走路由匹配,这样为视图函数巧妙的加上装饰器了
34 
35         # response = callback(request, *callback_args, **callback_kwargs)
36         # return response
37 
38     def process_response(self, request, response):
39         """
40         在这个环节已经通过了路由系统执行当前请求的视图函数了,一层层的返回字符串给用户
41         :param request:
42         :param response:
43         :return:
44         """
45         print(m1.process_response)
46         return response
47 
48     def process_exception(self, request, exception):
49         print(m1.process_exception)
50 
51     def process_template_response(self, request, response):
52         """
53         视图函数的返回值如果有render方法,才触发这个函数执行
54         :param request:
55         :param response:
56         :return:
57         """
58         print(m1.process_template_response)
59         return response
60 
61 
62 class M2(MiddlewareMixin):
63 
64     def process_request(self, request):
65         print(m2.process_request)
66 
67     def process_view(self, request, callback, callback_args, callback_kwargs):
68         print(m2.process_view)
69 
70     def process_response(self, request, response):
71         print(m2.process_response)
72         return response
73 
74     def process_exception(self, request, exception):
75         print(m2.process_exception)

注册中间件

 1 MIDDLEWARE = [
 2     django.middleware.security.SecurityMiddleware,
 3     django.contrib.sessions.middleware.SessionMiddleware,
 4     django.middleware.common.CommonMiddleware,
 5     django.middleware.csrf.CsrfViewMiddleware,
 6     django.contrib.auth.middleware.AuthenticationMiddleware,
 7     django.contrib.messages.middleware.MessageMiddleware,
 8     django.middleware.clickjacking.XFrameOptionsMiddleware,
 9     md.M1,
10     md.M2,
11 ]

 1.路由

urlpatterns = [
    path(‘index/‘, views.index),
]

2.视图

 1 from django.shortcuts import render, HttpResponse
 2 
 3 
 4 class Foo:
 5     def __init__(self, request, status, message):
 6         self.request = request
 7         self.status = status
 8         self.message = message
 9 
10     def render(self):
11         import json
12         result = 
13             status: self.status,
14             message: self.message
15         
16         return HttpResponse(json.dumps(result))
17 
18 
19 def index(request):
20     # print(‘index执行视图函数‘)
21     # return HttpResponse(‘.........‘)
22     return Foo(request, True, "错误信息")

 

我把几个函数都写在一起分步骤测试的  测试如下图:(正常情况如上图请求生命周期,process_exception和process_template_response如下)  

技术图片

上图测试的process_exception

总结下process_exception方法触发的机制流程图:

技术图片

下图是测试process_template_response:

技术图片技术图片 

总结下process_template_response:视图函数的返回值如果有render方法,才触发这个函数执行

 

 

 

 

总结:

     中间件是有序的,从上到小依次执行,本质是因为一个列表

    应用:如果要对请求批量操作的时候就用中间件做

    0.对用户请求缓存中有,我就直接给你,没有就执行视图后续操作(从内存拿数据比从磁盘快多了嘛)

    1.做黑名单

    2.对所有请求日志的记录

    3.做认证权限

    4.装饰器局部使用,全局使用啊

    5.自己也可以做csrf_token认证

      等等很多的看需求

 

以上是关于django之(中间件)middleware的主要内容,如果未能解决你的问题,请参考以下文章

Django进阶之中间件

django框架之中间件

django之(中间件)middleware

Django之中间件浅析

Django之中间件

[Django高级之中间件csrf跨站请求伪造]