中间件

作者: 戴维得 | 来源:发表于2017-10-04 13:37 被阅读0次

    django处理一个Request的过程是首先通过django 中间件,然后再通过默认的URL方式进行的。所以说我们要做的就是在django 中间件这个地方把所有Request拦截住,用我们自己的方式完成处理以后直接返回Response,那么我们可以简化原来的设计思路,把中间件不能处理的 Request统统不管,丢给Django去处理

    中间件的安装

    直接在django配置里面添加如下配置,Django本来就配置类好多中间件,中间件的执行顺序从上到下依次进行

    MIDDLEWARE = [
    'md.middleware.M1',  # 自定义的中间件
    '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',
    ]
    

    自定义中间件

    其实每一个中间件都是一个类,类里面的方法django已经帮我们规定好了

    from django.utils.deprecation import MiddlewareMixin
    
    
    class M1(MiddlewareMixin):
        # 方法和参数必须要按照人家的规定的写
        def process_request(self, request):
            print('process_request')  # 注意,request没有返回值
    
        def process_response(self, response):
            print('process_response')
            return response
    

    这样,django运行起来之后会先打印process_request,然后执行视图函数,视图函数执行完毕之后最后执行M1里面的process_response方法,也就是打印process_response

    注意:如果新版本的django不能导入中间件的话,完全可以自己写模块

    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
    

    将这段代码放到自己定义的中间键前面就可以了

    中间件和装饰器的区别

    中间件是针对所有的请求和返回,而装饰器只是针对某个函数的,装饰器的粒度更小一些

    中间件的方法

    Django的中间件就是一个类,类里面有五个方法

    • process_request 请求刚进来执行的方法,
    • process_response 请求回去的时候执行的方法,必须要有返回值
    • process_view 路由匹配,等最后一个request执行完毕后会跳到第一个路由匹配进行执行
    • process_exception 程序报错执行所有中间件的exception方法,从最后一个开始一直执行到第一个然后再返回到最后一个response执行
    • process_tempalte_response

    方法返回值

    • process_request 此方法不能有返回值,如果有返回值会直接执行与他平行的response,下面的不会执行 ,但是也可以对请求值进行判断,然后相应的复合条件的返回,不符合条件的不返回,也可以return None,和没有返回值是一个效果

    • process_response 必须要有返回值,因为他就是请求返回的时候执行的,没有返回值一定会报错,但是我们可以对返回值进行一定的修改

    • process_view 如果有返回值,会跳到最后一个response返回

    • process_exception 如果某个中间件捕捉到错误且返回值的话,直接跳到最后一个response执行

    应用场景

    由于中间件的特性,他的应用很广也很灵活

    用户验证

    class M1(MiddlewareMixin):
        if request.path_info == '/login/':
                return None
        # 方法和参数必须要按照人家的规定的写
        def process_request(self, request):
            if not request.session.get('user_info'):
                return redirect('/login/')
    
        def process_response(self, response):
            print('process_response')
            return response
    

    注意:

    1. 这个方法用到了session,session也是一个中间件,因此我们在安装这个中间件的时候必须要放在session中间件的下面,最好放在最下面

      MIDDLEWARE = [
      'django.middleware.security.SecurityMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware', # session中间件
      'django.middleware.common.CommonMiddleware',
      'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
      'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
      'md.middleware.M1', # 放在session中间件下面
      ]

    2. 注意前面对request.path_info的判断,如果不加这个判断的话,跳转login页面的时候又会进行一次判断session,如果不符合继续跳转,就会形成死循环,加这个判断的一次是,如果判断当前路径为login的话返回None,也就是继续执行。

    相关文章

      网友评论

          本文标题:中间件

          本文链接:https://www.haomeiwen.com/subject/omxcyxtx.html