Django--中间件

一. 中间件

中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,在全局上改变改变django的输入输出, 
  由于是在全局上改变的,所以要慎用(高手可自行忽略这句)

django中的setting.py文件中的MIDDLEWARE配置项就是中间件

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',
]

  从上图可以看出来,按照请求的顺序,在视图函数执行之前进行一些操作,可以在中间件中搞事情, 按照响应顺序,在视图函数执行之后进行一些操作,也可以在中间件中搞事情.

二 . 自定义中间件

  中间件可以定义五个方法: (主要是process_requestprocess_response)

1. process_request(self,request)
2. process_view(self,request,view_func,view_args,view_kwagrs)
3. process_template_response(self,request,response)
4. process_exception(self,request,exception)
5. process_response(self,request,response)
# 以上方法的返回值可以是None或者是HttpResponse对象, 如果是None, 则继续按照Django定义的规则向后继续执行, 如果是HttpResponse对象,则直接返回给用户.

  当用户发起请求的时候会从上到下一次经过所有的中间件,这个时候的请求是process_request, 最后到达views的函数中,views处理后,再依次从下到上穿过中间件,这个时候是process_response,最后返还给请求者

  

  自定义中间件的具体操作

1. 自己写一个类, 但是必须继承MiddlewareMinMixin
2. 在项目中创建一个包,名字一般叫utils,表示一个公用的组件,创建一个py文件.

  示例

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):
    #自定义中间件,有request方法说明请求来了要处理,有response方法说明响应出去时需要处理,不是非要写这两个方法,
    如果你没写process_response方法,那么会一层一层的往上找,哪个中间件有process_response方法就将返回对象给哪个中间件
def process_request(self, request): print("MD1里面的 process_request") def process_response(self, request, response): print("MD1里面的 process_response") return response

 

  process_request

1.process_request有一个参数,就是request,这个request和视图函数中的request是一样的.
2.它的返回值可以是None,也可以是HttpResponse对象,返回值是None的话,按照正常流程继续走,交给下一个中间件处理,
  如果是HttpResponse对象,Django将不执行视图函数,而将相应的对象返回给浏览器

  

  多个中间件是Django执行process_request的示例

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")

  定义两个中间件,我们需要把它们加入到MIDDLEWARE配置中的注册表中:

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',
    'utils.middlewares.MD1',  # 自定义中间件MD1,这个写的是所在路径,
    'utils.middlewares.MD2'  # 自定义中间件MD2
]

  我们开始访问一个视图,终端打印的是:

MD1里面的 process_request
MD2里面的 process_request
app01 中的 index视图

  由此可知,中间件是在视图函数之前执行,并且这个request就相当于一个接力棒一样,我用完了给你你才能用,一共就一个request.

  process_response

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("MD1里面的 process_request")
        #不必须写return值

    def process_response(self, request, response):#request和response两个参数必须有,名字随便取
        print("MD1里面的 process_response")
        #print(response.__dict__['_container'][0].decode('utf-8')) #查看响应体里面的内容的方法
     return response  #必须有返回值,写return response  ,这个response就像一个接力棒一样
        #return HttpResponse('瞎搞') ,如果你写了这个,那么你视图返回过来的内容就被它给替代了

class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")

    def process_response(self, request, response): #request和response两个参数必须要有,名字随便取
        print("MD2里面的 process_response") 
        return response  #必须返回response,不然你上层的中间件就没有拿到httpresponse对象,就会报错

  访问一个视图,看看终端的输出:

MD1里面的 process_request
MD2里面的 process_request
app01 中的 index视图
MD2里面的 process_response
MD1里面的 process_response

  

   

有了中间件,我们在做大量的同样的操作的时候只需要在中间件里搞一下就好,比如在做session认证的时候,不需要在用装饰器一个一个的加了,
  但是这个中间件一定要放在Django自带的那个session的中间件的下面,因为我们要用到里面功能. 一定要注意放的顺序

  session认证的中间件示例

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render
from django.urls import reverse

class M1(MiddlewareMixin):

    def process_request(self, request):

        #设置路径白名单,只要访问的是login登陆路径,就不做这个session认证
        if request.path in [reverse('login'),]:
            return None   # 继续往下执行
        else:
            ret = request.session.get('session_login')
            if ret:
                return None
            else:
                return redirect(reverse('login'))

    def process_response(self, request, response):
        print('M1响应部分')
        # print(response.__dict__['_container'][0].decode('utf-8'))
        return response
       

  

猜你喜欢

转载自www.cnblogs.com/attila/p/10497435.html
今日推荐