Django 中间件的研究

太过爱你忘了你带给我的痛 2022-06-11 03:44 261阅读 0赞
  • 闲来无事,看到MIDDLEWARE 这个列表,想一探究竟
  • 先上几个参考链接:
  • 涂伟忠自强学堂
  • 戳这里这篇博客
  • 官网文档中间件

开篇

  • 中间件是什么?

    1. 中间件的本质是一个类实例对象或者一个函数对象,这些对象提供过滤请求、响应、处理异常等功能。重点关键字:过滤
    2. 1 中间件可以是类的形式也可以是函数的形式,见官网说明
  • 上结论先

    1. 从请求到响应阶段 都可以进行拦截
    2. 第一阶段 处理 process_request 列表 返回None 或者HttpResponse对象
    3. 第二阶段 通过路由映射关系表获取视图函数地址 获得函数(进入视图预处理链process_view) 或者没有(404)--进入响应处理链
    4. 第三阶段 处理 process_view列表(前提是已经有匹配到的视图函数) process_view 返回None或者HttpReponse
    5. 第四阶段 处理视图函数 生成响应
    6. 第五阶段 处理异常检测 处理异常 返回响应或者None None 表示交给下一层处理异常
    7. 第六阶段 处理 process_response 列表 不管从哪里发出的响应都要从响应链走,要么从中间走,要么从底层走
    8. 中间件类提供过滤请求、响应的钩子,即process_requestprocess_response等,所有钩子按照中间件类在中间件列表中的顺序组成新的钩子列表,process_response响应钩子、process_exception异常处理钩子是反向执行的
  • 上代码(代码所在的文件在项目中的位置不重要,重要的是能找到中间件类的路径)

    1.11 版本的兼容写法,当然你也可以自己手写一个类,不是很麻烦,我使用继承

    appname/middleware.py

    每一个类都可以根据需要提供不同的钩子,这些钩子组成钩子列表

    from django.utils.deprecation import MiddlewareMixin
    class Row1(MiddlewareMixin):

    1. def process_request(self, request):
    2. print('row1 请求', request)
    3. # response = HttpResponse("row1 response")
    4. # return response
    5. def process_response(self, request, response):
    6. print('row1 响应', request, response)
    7. return response
    8. def process_view(self, request, view_func, view_args, view_kwargs):
    9. print('row1 view', view_func)

    class Row2(MiddlewareMixin):

    1. def process_request(self, request):
    2. print('row2 请求', request)
    3. def process_response(self, request, response):
    4. print('row2 响应', request, response)
    5. return response
    6. def process_view(self, request, view_func, view_args, view_kwargs):
    7. print('row2 view', view_func)
    8. def process_exception(self, request, exception):
    9. print('row2 exception', exception)
    10. return HttpResponse(exception);
  1. class Row3(MiddlewareMixin):
  2. def process_request(self, request):
  3. print('row3 请求', request)
  4. def process_response(self, request, response):
  5. print('row3 响应', request, response)
  6. if response.status_code == 404:
  7. response = HttpResponse('404')
  8. return response
  9. def process_view(self, request, view_func, view_args, view_kwargs):
  10. print('row3 view', view_func)
  11. def process_exception(self, request, exception):
  12. print('row3 exception', exception)
  • 上配置
  • MIDDLEWARE中 中间件类所处的顺序很重要,决定了每个中间件类提供的钩子的执行顺序

    MIDDLEWARE = [

    1. 'django.middleware.security.SecurityMiddleware',
    2. 'django.contrib.sessions.middleware.SessionMiddleware',
    3. 'django.middleware.common.CommonMiddleware',
    4. 'django.middleware.csrf.CsrfViewMiddleware',
    5. 'django.contrib.auth.middleware.AuthenticationMiddleware',
    6. 'django.contrib.messages.middleware.MessageMiddleware',
    7. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    8. 'booktest.middleware.Row1',
    9. 'booktest.middleware.Row2',
    10. 'booktest.middleware.Row3',

    ]

  • 调用的view函数

    Create your views here.

    def index(request):

    1. # raise Exception('异常')
    2. return HttpResponse("<b>世界如此美妙<b>")
  • 上运行结果

    July 29, 2017 - 05:17:13
    Django version 1.11, using settings ‘test6.settings’
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.
    生成应用
    row1 请求
    row2 请求
    row3 请求
    row1 view
    row2 view
    row3 view
    row3 响应
    row2 响应
    row1 响应
    [29/Jul/2017 05:17:55] “GET / HTTP/1.1” 200 24

  • 其他

    1. 感兴趣的话可以手动抛出异常来看看效果
    2. 1 process_request 阶段, 每个钩子都可以返回None或者HttpResponse对象(自己构造一个),如果返回None,则下一个钩子接着处理,直到URL关系映射表执行匹配操作;如果返回HttpResponse 则从当前中间件层开始反向返回结果,最核心层的view函数不会被执行,当前中间件层的下面中间件类提供的处理响应钩子也不会被执行(1.11版本)
    3. 2 当所有的process_request钩子执行完毕,都返回None,则进入路由关系映射匹配阶段,即根据请求路径找能处理响应的view函数,有两个结果:找到了--->进入process_view钩子列表处理阶段;没找到----->进入process_response钩子列表处理阶段
    4. 3 process_view 处理阶段可以,每个钩子可以返回None也可以返回HttpResponse 对象,参上
    5. 4 process_response 阶段,我们可以篡改响应,比如没找到视图函数,我们可以给捏造一个扔给客户
    6. 5 process_request--->路由关系映射找到视图函数--->process_view 都处理完成了,并且找到了视图函数,中间没有使用钩子构造响应,则view函数开始工作:执行业务逻辑代码,从数据库拉去数据,给模板填坑,构造响应对象
    7. 6 5这个过程可能抛出异常,抛出异常则进入异常钩子列表process_exception,如果所有的异常处理钩子都不能处理异常,程序把异常通过process_response 钩子列表扔给客户

    以上 就是整个流程,当然,没有涉及process_template_response钩子列表

  • 上个简图 input/output
  • 每一个中间件都想一张过滤网
    这里写图片描述
  • 上个网络盗图

这里写图片描述
* 上第二个网络图
这里写图片描述

收尾

  • 我们拿这些中间件干什么呢?

    1. 答:玩
    2. 认真的回答:那它做IP拦截,客户端设备识别,过滤恶意请求等等
  • 上面的介绍并不全面,还有很多细节没介绍,但不影响对请求/响应整个流程的理解

发表评论

表情:
评论列表 (有 0 条评论,261人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Django中间技术

    怎么理解中间件呢,其实如果你使用过java和数据库你就知道,中间件技术是两个模块中间的桥梁,就好比两块大陆之间的一座桥梁 > 如果需要详细了解中间件技术可以查看此文档

    相关 django中间

    中间件函数是django框架给我们预留的函数接口,让我们可以干预请求和应答的过程。 ![1682918-20190610110717958-1367766905.png][]