首页 > 其他分享 >django中间件

django中间件

时间:2022-12-28 18:56:53浏览次数:44  
标签:process 中间件 request django 模块 response

目录

django中间件

中间件简介

1.流程图--介绍中间件

image

2.django默认有七个中间件 并且还支持用户自定义中间件

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

这七个中间件程序会在请求来时自上而下依次的处理request请求,在响应走时自下而上依次处理response响应。

3.中间件的功能

​ 网站访问频率的校验 用户权限的校验等全局类型的功能需求

4.前期我们要访问post请求,中间件的第四个字符串妨碍了简单post请求,初期阶段我们将其注释掉了。

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

5.解析中间件原理

​ 这七个字符串实际上对应的是中间件程序存储的路径

image

我们顺着路径的文件,点进去可知

image

由上述图可知,

1.七个中间件都继承了MiddlewareMixin类
2.都几乎有process_request和process_response函数
3.都必须传入参数
    process_request需要传入request参数;
    process_response需要传入request和response两个参数,必须返回response。
    

自定义中间件(重要)

如何自定义中间件
	1.创建存储自定义中间件代码的py文件或者目录(如果中间件很多)
	2.参考自带中间件的代码编写类并继承
 	3.在类中编写五个可以自定义的方法
 	4.一定在配置文件中注册中间件才可以生效

1,创建存储自定义中间件代码的py文件或者目录

image

2.编写自定义的中间件(在mymiddlie中编写MyMiddleware001)

image

3.编写好中间件,一定要去settings里的Middleware中注册自定义的中间件

image

中间件的顺序

我们只是定义了process_reqtest和process_response函数,我们想看看执行的顺序的,我们可以做一个小测试

mymiddle.py(自定义的中间件)

from django.utils.deprecation import MiddlewareMixin

class MyMiddleware001(MiddlewareMixin):
    def process_request(self,request):
        print('from MyMiddleware001 process_request')

    def process_response(self,request,response):
        print('from MyMiddleware001 process_response')
        return response

class MyMiddleware002(MiddlewareMixin):
    def process_request(self,request):
        print('from MyMiddleware002 process_request')

    def process_response(self,request,response):
        print('from MyMiddleware002 process_response')
        return response

当我们从网页向URL发送请求时,请求通过了网关接口到达了中间件,在中间件的执行过程是自上而下,从而经过路由层>>视图层>>>等,当响应是经过中间件的时候是自下而上的,返回给网关接口,再打包给浏览器,

image

后端打印

image

如果我们还想测试如果遇到HttpResponse对象,会怎么样?看下面的解释

django中间件两个基本方法

process_request

1.请求来的时候会从上往下依次经过每一个注册的中间件里面的该方法 如果没有则直接跳过
2.如果该方法自己返回了HttpResponse对象那么不再往后执行而是直接原路返回

如果请求遇到了process_request方法,该方法返回了HttpResponse对象,如下

class MyMiddleware001(MiddlewareMixin):
    def process_request(self,request):
        print('from MyMiddleware001 process_request')
        return HttpResponse('你没有权限执行下面的中间件')  # 遇到了HttpResponse对象

    def process_response(self,request,response):
        print('from MyMiddleware001 process_response')
        return response

他经过的行径如黄色箭头,请求通过网关到中间件自上而下到达了中间件MyMiddleware001,就会直接执行MyMiddleware001的process_response方法,直接原路返回,不会走下面的中间件MyMiddleware002。

image

process_response

1.响应走的时候会从下往上依次经过每一个注册了的中间件里面的该方法 如果没有则直接跳过
2.该方法有两个先request和response 形参response指代的就是后端想要返回给前端浏览器的数据 该方法必须返回该形参 也可以替换

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
class MyMiddleware001(MiddlewareMixin):
    def process_request(self,request):
        print('from MyMiddleware001 process_request')

    def process_response(self,request,response):
        print('from MyMiddleware001 process_response')
         # return response
		return HttpResponse('中间1直接返回了,返回了response')

注意:

1.一个请求经过了中间件,如果在执行process_request方法的时候直接返回了HttpResponse对象那么会原路返回执行自定义中间件的process_response 不是执行所有。

​ 2.在flask中,是从最底层中间程序的响应函数开始执行的

django中间件三个了解得方法

1.process_view
	路由匹配成功之后执行视图函数/类之前自动触发(顺序同process_request)
2.process_exception
	视图函数/类执行报错自动触发(顺序同process_response)
3.process_template_response
	视图函数/类返回的HttpResponse对象含有render并且对应一个方法的时候自动触发(顺序同process_response)

基于django中间件的功能设计

将各个功能制作成配置文件的字符串形式

​ 1.如果想拥有该功能就要编写对应的字符串

​ 2.如果不想有该功能则注释掉对应的字符串

中间件是如何实现字符串导入模块的?

importlib模块

importlib可以帮助我们用字符串导入模块,拿到一个模块名的字符串,它可以搜索模块,并执行导入操作:

import importlib   # 引入模块
s1 = 'bbb.b'  # aaa.bbb.ccc.b
res = importlib.import_module(s1)  # from aaa.bbb.ccc import b
print(res)  # <module 'bbb.b' from 'D:\\pythonProject03\\djangomiddle\\bbb\\b.py'>
s2 = 'aaa'
res=importlib.import_module(s2) # 相当于import aaa 并将模块设置为res
'''注意字符串的结尾最小单位只能是py文件 不能是py文件里面的变量名'''

思考1:思考django中间件是如何处理的(最小单位是类名)?

思考2:模拟编写一个消息通知功能(微信、qq、邮箱)?

方式一: 基于函数封装的版本

​ 缺点: 没有眼前一亮的感觉,很一般

方式二: 基于django中间件的功能设计

​ 优点: 眼前一亮,回味无穷

基于django中间件实现功能插拔式设计

1.importlib
	通过字符串导入模块
2.从右开始切割字符串
	rsplit
3.反射
	将模块名看成是对象通过反射回去该模块中字符串对应的名字
4.面向对象的多态性

模块对象的反射

在python中一切皆对象,模块也是一种对象,模块的名称空间中的名字就是模块对象的属性。所以对于一个模块,我们可以通过反射的方式取到其中的类、函数、变量等名字:

仿django配置文件注册

知道以上两个知识点,我们也可以让仿中间件的注册过程,写好类后,用字符串保存路径,然后顺序执行。核心代码就是将字符串识别成可以执行的类程序:

# MyMiddleWare文件夹midware01.py中
class MidWare01(MiddlewareMixin):
    def process_request(self, request):
        print('from MidWare01 request')
        
# MyMiddleWare文件夹midware02.py中
class MidWare02(MiddlewareMixin):
    def process_request(self, request):
        print('from MidWare01 request')
        
# 注册配置
MIDWARE_LIST = [
    'MyMiddleWare.midware01.MidWare01',
    'MyMiddleWare.midware02.MidWare02',
]

# 按照注册顺序,执行每个类中的process_request方法
import importlib
def all_exec(request):
    for full_path in MIDWARE_LIST:
        # 将字符串切割为模块路径和类名
	    path, cls_name = full_path.rsplit('.', max_split=1) 
        # 通过模块路径字符串拿到模块名
        module_name = importlib.import_module(path)  
        # 通过模块名反射拿到类名
        cls = getattr(module_name, cls_name)  
        # 通过类产生对象
        obj = cls()  
        # 通过对象使用方法
        obj.process_request(request)  # 多态的思想,因为大家的这个功能一致,所以方法名也该一致

标签:process,中间件,request,django,模块,response
From: https://www.cnblogs.com/zhanglanhua/p/17011036.html

相关文章

  • django查询中values_list(flat=True) 是什么意思?
    1.values()departments=models.Department.objects.filter(dpm_status=1).values('dnp__name')print(departments)# queryset中是一个个字典。“departments......
  • django 自带auth模块 实现 用户 注册、登录、验证、注销
    Auth模块只要是跟用户相关的登陆、注册、校验、修改密码、注销、验证用户是否登陆 内容详细Auth模块"""其实我们在创建好一个django项目之后直接执行数据库迁移......
  • django csrf跨站,CBV添加装饰器,auth认证模块
    djangocsrf跨站,CBV添加装饰器,auth认证模块内容概要csrf跨站请求伪造csrf相关校验策略CBV添加装饰器的多种方式auth认证模块BBS项目需求分析内容详情csrf跨站请求......
  • 1006.Django模型基础01
    一、Django的ORM简介1.ORM概念:对象关系映射(ObjectRelationalMapping);2.ORM优势:不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。 django模型映射关系模型......
  • 21.中间件
    概述中间件类型常用中间件......
  • django 11 django中间件
    今日内容详细目录今日内容详细django中间件三个了解的方法基于django中间件实现功能的插拔式设计cookie与session简介django操作cookiedjango操作sessiondjango中间件三......
  • django 12 csrf跨站请求伪造
    今日内容详细目录今日内容详细csrf跨站请求伪造csrf校验策略csrf相关装饰器auth认证模块auth认证相关模块及操作扩展auth_user表csrf跨站请求伪造钓鱼网站:模仿一个正规......
  • django 10 forms组件
    今日内容详细目录今日内容详细forms组件渲染标签forms组件展示信息forms组件校验补充forms组件参数补充forms组件源码剖析modelform组件django中间件forms组件渲染标签<......
  • django之AJAX组件
    目录Ajax组件基本语法Content-Type(数据编码格式)ajax发送json格式数据ajax携带文件数据ajax补充说明Ajax组件AJAX(AsynchronousJavascriptAndXML)翻译成中文就是“异步......
  • cookie与session django中间件 插拔式设计
    今日内容总结django中间件三个了解的方法(较冷门)#1.process_view 路由匹配成功之后执行视图函数/类之前自动触发(顺序同proess_request)#2.process_exception ......