Django 中间件详解


仁爱扯刺猬
仁爱扯刺猬 2022-09-21 09:17:04 63866
分类专栏: 资讯

Django 中间件

一、请求生命周期

以下图是客户端发起一次http请求的流程:
在这里插入图片描述
注意:django框架不包括socket,要借助图中两个模块实现socket,进行客户端和服务器通信。wsgi性能较弱,一般测试开发用;企业中用uwsgi比较好,性能强,并发好

二、中间件简介:

上图可知,在请求到达视图之前,会依次执行中间件,视图返回的响应,依次倒序执行中间件

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

在django项目的setting.py文件中,有一个MIDDLEWARE列表,其中每一个元素都是一个中间件

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'qinspect.middleware.QueryInspectMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
" style="">
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 在setting.py中注册中间件:

    MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'qinspect.middleware.QueryInspectMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'corsheaders.middleware.CorsMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'libs.api_tools.middleware.CustomizeMiddleware'   创建的自定义中间件类(路径 + 类名)
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意:django 1.10之后django无法导入,因此直接把MiddlewareMixin类拿过来继承就好了:

    class MiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            return response
    
    
    class CustomizeMiddleware(MiddlewareMixin):   自定义类,继承MiddlewareMixin
        ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    同样也是在setting.py中注册中间件:

    MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'qinspect.middleware.QueryInspectMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'corsheaders.middleware.CorsMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'libs.api_tools.middleware.CustomizeMiddleware'   创建的自定义中间件类(路径 + 类名)
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    五、中间件五个方法:

    process_request 请求进来时执行;

    • 不能有返回值,若在process_request有返回值,那么下面的中间件将不会执行,后面的URL以及视图函数也不会执行,直接执行当前的中间件的process_response方法。

       请求时,仅让IP192.168.1.1才可以进行访问
      from django.shortcuts import HttpResponse
      class CustomizeMiddleware(MiddlewareMixin):
      
          def process_request(self, request, response):
              allowed_ip = ['192.168.1.1',]
               允许/禁止访问的ip地址列表,判断请求ip, 放行/阻拦
              if request.META.get('REMOTE_ADDR') not in allowed_ip:
                  return HttpResponse('您的IP地址无权访问')
              else:
                  return None
      
          def process_response(self, request, response):
              return response
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    process_response 返回响应时执行;

    • 默认情况下返回response, 即视图函数的返回值,如果在这个方法中自定义了返回值,将返回自定义返回值。

      class CustomizeMiddleware(MiddlewareMixin):
      
          def process_response(self, request, response):
              print('处理一些逻辑条件等......')
              return response
      
      • 1
      • 2
      • 3
      • 4
      • 5

    process_view 视图函数;

    • 执行过程:

      执行完process_request  →  路由分发(dispatch)  →  process_view  →  视图函数  → process_response
      
      • 1
      from django.utils.deprecation import MiddlewareMixin
      from django.shortcuts import HttpResponse
      
      class CustomizeMiddleware1(MiddlewareMixin):
          def process_request(self,request):
              print("...来自中间件1的请求...")
          def process_response(self,request,response):
              print("...来自中间件1的返回...")
              return response
      
          def process_view(self, request, callback, callback_args, callback_kwargs):
              print("...中间件1view...")
      
      class CustomizeMiddleware2(MiddlewareMixin):
          def process_request(self,request):
              print("...来自中间件2的请求...")
          def process_response(self,request,response):
              print("...来自中间件2的返回...")
              return response
          def process_view(self, request, callback, callback_args, callback_kwargs):
              print("...中间件2view...")
      
      class CustomizeMiddleware3(MiddlewareMixin):
          def process_request(self,request):
              print("...来自中间件3的请求...")
          def process_response(self,request,response):
              print("...来自中间件2的返回...")
              return response
          def process_view(self, request, callback, callback_args, callback_kwargs):
              print("...中间件3view...")
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
       输出结果为:
      ...来自中间件1的请求..
      ...来自中间件2的请求..
      ...来自中间件3的请求..
      ...中间件1view...
      ...中间件2view...
      ...中间件3view...
      ...来自中间件3的返回...
      ...来自中间件2的返回...
      ...来自中间件1的返回...
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      如图所示:
      在这里插入图片描述

    • 当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。

    process_exception 视图中出现异常,就会被执行(默认不执行);

     定义一个提示错误信息页面
    from django.shortcuts import HttpResponse
    
    class CustomizeMiddleware(MiddlewareMixin):
    
        def process_exception(self, request, exception):
            return HttpResponse('在处理中间件时,抛出了异常,就会走这里哦~')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    process_template_response 若返回的对象有render方法,就会被执行(默认不执行);

    process_template_response(self, request, response)
    
    • 1
    • 它的参数,一个HttpRequest对象,response是TemplateResponse对象(由视图函数或者中间件产生)
    • process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)
    • 视图函数执行完之后,立即执行了中间件的process_template_response方法,顺序是倒序,先执行CustomizeMiddleware3的,再执行CustomizeMiddleware2的,接着执行了视图函数返回的HttpResponse对象的render方法,返回了一个新的HttpResponse对象,接着执行中间件的process_response方法。
    文章知识点与官方知识档案匹配,可进一步学习相关知识
    Python入门技能树Web应用开发 Django127519 人正在系统学习中

    网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

    本文链接:https://www.xckfsq.com/news/show.html?id=8750
    赞同 0
    评论 0 条
    仁爱扯刺猬L0
    粉丝 0 发表 7 + 关注 私信
    上周热门
    Kingbase用户权限管理  2023
    信刻全自动光盘摆渡系统  1753
    信刻国产化智能光盘柜管理系统  1422
    银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1021
    银河麒麟打印带有图像的文档时出错  927
    银河麒麟添加打印机时,出现“server-error-internal-error”  718
    麒麟系统也能完整体验微信啦!  660
    统信桌面专业版【如何查询系统安装时间】  636
    统信操作系统各版本介绍  627
    统信桌面专业版【全盘安装UOS系统】介绍  601
    本周热议
    我的信创开放社区兼职赚钱历程 40
    今天你签到了吗? 27
    信创开放社区邀请他人注册的具体步骤如下 15
    如何玩转信创开放社区—从小白进阶到专家 15
    方德桌面操作系统 14
    我有15积分有什么用? 13
    用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
    如何让你先人一步获得悬赏问题信息?(创作者必看) 12
    2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
    中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

    添加我为好友,拉您入交流群!

    请使用微信扫一扫!