Django之中间件

目录

  1、说明

  2、自定义中间件

  3、测试

 

一、说明

1、简述

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

在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下。

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',
    "rbac.middleware.rbac.RbacMiddleware"  # 注册自定义中间件
]

 2、用途

  django中间件可用作下面:

  用户登录
  日志记录
  crsf:对所有的post请求做了一个验证
  session
  权限管理

注意:
  对于所有请求的批量做处理的时候用中间件
  单独对某几个函数做处理的时候用装饰器

 3、组成部分

与mange.py在同一目录下的文件夹 rbac/middleware下的rbac.py文件中的RbacMiddleware类

中间件中可以定义下面的方法,分别是:

  • 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对象,则直接将该对象返回给用户。

(1)process_request和process_response的执行过程

(2)process_view的执行过程

(3)process_excepttion

当views的函数中出现错误时,就会执行process_exception方法

 

 

 二、自定义中间件

1、创建中间件

class RequestExeute(MiddlewareMixin):
      
    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        i =1
        pass
    def process_exception(self, request, exception):
        pass
      
    def process_response(self, request, response):
        return response

2、注册中间件

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',
    "rbac.middleware.rbac.RbacMiddleware"
]

三、测试

 1、验证process_request、process_response,其中process_request无返回值

注册md

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',
    'app01.middleware.test.Md1',
    'app01.middleware.test.Md2',
]

自定义md,路径是app01/middleware/test.py

class Md1(MiddlewareMixin):  #必须继承
    def process_request(self,request):
        print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等")
        # 如果无返回值,就继续执行后续中间件和视图函数
        # 如果有返回值,就执行自己的process_response和上面的response

    def process_response(self,request,response):
        print("md1====process_response1")
        return response   #必须有返回值

class Md2(MiddlewareMixin):
    def process_request(self,request):
        print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等")

    def process_response(self,request,response):
        print("md2====process_response2")
        return response

附:继承的MiddlewareMixin,django已定义。

class MiddlewareMixin:
    def __init__(self, get_response=None):
        self.get_response = get_response
        super().__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

结果

md1===process_request。在执行views.py内容之前可做一些验证、预操作等
md2====process_request2。在执行views.py内容之前可做一些验证、预操作等
这里是主逻辑index.html
md2====process_response2
md1====process_response1

 

 2、验证process_request、process_response,其中process_request有返回值

 自定义md,路径是app01/middleware/test.py

class Md1(MiddlewareMixin):  #必须继承
    def process_request(self,request):
        print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等")
        # 如果无返回值,就继续执行后续中间件和视图函数
        # 如果有返回值,就执行自己的process_response和上面的response
        return HttpResponse("md1====process_request的return值")

    def process_response(self,request,response):
        print("md1====process_response1")
        return response   #必须有返回值

class Md2(MiddlewareMixin):
    def process_request(self,request):
        print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等")

    def process_response(self,request,response):
        print("md2====process_response2")
        return response

结果

md1===process_request。在执行views.py内容之前可做一些验证、预操作等
md1====process_response1

 3、验证process_view,无return

 自定义

class Md1(MiddlewareMixin):  #必须继承
    def process_request(self,request):
        print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等")
        # 如果无返回值,就继续执行后续中间件和视图函数
        # 如果有返回值,就执行自己的process_response和上面的response
        # return HttpResponse("md1====process_request的return值")

    def process_response(self,request,response):
        print("md1====process_response1")
        return response   #必须有返回值

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("md1=====process_view")


class Md2(MiddlewareMixin):
    def process_request(self,request):
        print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等")

    def process_response(self,request,response):
        print("md2====process_response2")
        return response
    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("md2=====process_view")

结果

md1===process_request。在执行views.py内容之前可做一些验证、预操作等
md2====process_request2。在执行views.py内容之前可做一些验证、预操作等
md1=====process_view
md2=====process_view
这里是主逻辑index.html
md2====process_response2
md1====process_response1

 4、验证process_view,有return

class Md1(MiddlewareMixin):  #必须继承
    def process_request(self,request):
        print("md1===process_request。在执行views.py内容之前可做一些验证、预操作等")
        # 如果无返回值,就继续执行后续中间件和视图函数
        # 如果有返回值,就执行自己的process_response和上面的response
        # return HttpResponse("md1====process_request的return值")

    def process_response(self,request,response):
        print("md1====process_response1")
        return response   #必须有返回值

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("md1=====process_view")
        return HttpResponse("md1=====process_view")  # 有return值



class Md2(MiddlewareMixin):
    def process_request(self,request):
        print("md2====process_request2。在执行views.py内容之前可做一些验证、预操作等")

    def process_response(self,request,response):
        print("md2====process_response2")
        return response
    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("md2=====process_view")

结果

md1===process_request。在执行views.py内容之前可做一些验证、预操作等
md2====process_request2。在执行views.py内容之前可做一些验证、预操作等
md1=====process_view
md2====process_response2
md1====process_response1

 

 4、验证process_exception

 待续

5、验证process_template_responseprocess

process_template_response(self,request,response)

只有当views函数中返回的对象中具有render方法,是就会直接process_template_responseprocess

posted @ 2018-04-03 17:06  fat39  阅读(135)  评论(0编辑  收藏  举报