django的中间件

中间件

MiddleWare,是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。【输入指代的就是客户端像服务端django发送数据,输出指代django根据客户端要求处理数据的结果返回给客户端】

钩子就是编程开发的一个术语,hook,钩子可以理解为一段代码(要么是类,要么是函数),它的作用就类似日常生活中墙上的钩子,不需要的时候,挂在墙上不会占用房子的空间,但是需要的时候我们可以把一些物件挂在上面。

这种中间件在平时不使用情况下不会耗费任何的性能,如果编写了中间件以后,可以在特定的条件下,全局执行!!

文档: https://docs.djangoproject.com/zh-hans/2.2/topics/http/middleware/

内置中间件

django框架内部声明了很多的中间件,这些中间件有着各种各种的用途,有些没有被使用,有些被默认开启使用了。

而被开启使用的中间件,都是在settngs.py的MIDDLEWARE中注册使用的。

# 中间件列表
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware', # 安全监测相关的中间件,防止页面过期, js跨站脚本攻击xss
    'django.contrib.sessions.middleware.SessionMiddleware', # session加密和读取和保存session相关
    'django.middleware.common.CommonMiddleware', # 通用中间件,用于给url进行重写
    'django.middleware.csrf.CsrfViewMiddleware', # 防止网站遭到csrf攻击的
    'django.contrib.auth.middleware.AuthenticationMiddleware', # 用户认证的中间件
    'django.contrib.messages.middleware.MessageMiddleware', # 错误提示信息的中间件【提示错误信息,一次性提示】
    'django.middleware.clickjacking.XFrameOptionsMiddleware', # 用于防止点击劫持攻击的 iframe标签
]

自定义中间件

django中提供了2种不同的中间件声明方式.主要在django1.9或者2.0出现

函数式中间件

def simple_middleware(get_response):
    # 自定义中间件
    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        print("--------------视图执行之前---------------")
        # 记录访问用户记录的信息,识别判断黑名单,白名单,判断用户是否登录, 判断用户是否拥有访问权限.....
        # 视图执行之前
        response = get_response(request) # 视图调用
        # 视图执行之后
        print("-------------视图执行以后----------------")
        # 记录用户的操作历史,访问历史,日志记录, 资源的回收...
        return response

    return 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',
    'middle.simple_middleware', # 没有特殊要求,一般自己定义的中间件写在最后
]

因为中间件一旦注册了以后, 会在全局生效, 所以我们访问任何一个视图都可以看到中间件执行的过程.

所以我们在cbv/views.py编写了一个测试的视图.代码:

from django.http.response import HttpResponse
class HomeView(View):
    def get(self,request):
        print( "---------------视图执行了---------------" )
        return HttpResponse("ok")

最终,访问视图,效果如下:

 

 

 

类中间件

和函数式的中间件一样,我们一般都会保存在一个独立的文件中.把所有的中间件按不同的业务存放在一块,.

def simple_middleware(get_response):
    # 自定义中间件
    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        print("--------------视图执行之前---------------")
        # 记录访问用户记录的信息,识别判断黑名单,白名单,判断用户是否登录, 判断用户是否拥有访问权限.....
        # 视图执行之前
        response = get_response(request)
        # 视图执行之后
        print("-------------视图执行以后----------------")
        # 记录用户的操作历史,访问历史,日志记录, 资源的回收...
        return response

    return middleware

from django.utils.deprecation import MiddlewareMixin
from django.http.response import HttpResponse
class CustomMiddleware(MiddlewareMixin):
    """中间件类"""
    def process_request(self,request):
        # 方法名是固定的,该方法会在用户请求访问路由解析完成以后,调用视图之前自动执行
        print("1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法")
        # 用途:权限,路由分发,cdn,用户身份识别,白名单,黑名单...
        # 注意,此方法不能使用return,使用则报错!!!

    def process_view(self,request,view_func, view_args, view_kwargs):
        # 用途:进行缓存处理,识别参数,根据参数查询是否建立缓存
        print("2. process_view在视图接受了参数以后,没有执行内部代码之前")
        # 可以返回response对象, 如果返回response对象以后,则当前对应的视图函数将不会被执行
        # return HttpResponse("ok")
        # 也可以不返回response,则默认返回None,django就会自动执行视图函数

    def process_response(self,request,response):
        print("4. process_response在视图执行以后,才执行的")
        # 用途:记录操作历史, 记录访问历史,修改返回给客户端的数据, 建立缓存
        # 必须返回response对象,否则报错!!
        return response

    def process_exception(self, request, exception):
        print(exception)
        # 用途:进行异常的处理或者记录错误日志
        print("5. process_exception会在视图执行发生异常的时候才会执行")

    def process_template_response(self,request, response):
        # 用途:建立页面缓存
        print("6. process_template_response只有在视图调用了模板以后,才会执行!!!")
        return response

中间件类和函数式中间件的注册方式雷同,也是在setting.py中直接注册.

# 中间件列表
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware', # 安全监测相关的中间件,防止,页面过期, js跨站脚本攻击xss
    'django.contrib.sessions.middleware.SessionMiddleware', # session加密和读取和保存session相关
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 'middle.simple_middleware',
    'middle.CustomMiddleware',
]

从上面不管是函数式中间件还是中间件类,他们的执行顺序都是类似的.也就是部分的方法在视图执行之前执行,部分方法是在视图执行之后执行的.

终端执行结果:

# 没有异常
1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法
2. process_view在视图接受了参数以后,没有执行内部代码之前
视图执行了!!!
4. process_response在视图执行以后,才执行的

# 视图中有异常
1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法
2. process_view在视图接受了参数以后,没有执行内部代码之前
视图执行了!!!
5. process_exception会在视图执行发生异常的时候才会执行:  error
4. process_response在视图执行以后,才执行的

如果多个中间件一起执行,效果如下

1-1 视图执行之前的代码 # 【simple_middle】
1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法 # 【CustomMidleWare】
2. process_view在视图接受了参数以后,没有执行内部代码之前# 【CustomMidleWare】
视图执行了!!!# 【视图代码】
4. process_response在视图执行以后,才执行的 # 【CustomMidleWare】
1-2 视图执行之后的代码 # 【simple_middle

从上面的打印结果可以看到,中间件是包含了视图代码的执行,所以中间件的执行顺序,是回环式执行

 

 

 

 

posted @ 2021-07-06 16:07  Fleeting__Time  阅读(93)  评论(0编辑  收藏  举报