Django 基于中间件思想编写项目

1. 引子

1. Django的settings配置文件中的中间件编写方式如下所示

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

2. 我们可以将其看作是列表中包含了多个字符串,但是字符串的作用其实类似于模块,如下示例

			from django.middleware.security import SecurityMiddleware

3. 如果我们也想实现将一个个模块变成字符串的导入形式,就需要使用到一个叫做 'importlib' 的模块

2. importlib 模块

该模块可以通过字符串的形式导入模块

常规导入方式

		from b import c

结果如下图所示,打印模块的结果是:
<module 'b.c' from 'F:\\python project\\pythonProject_importlib\\b\\c.py'>		

在这里插入图片描述

字符串导入方式
		
		import importlib
		# 创建字符串
		module_path = 'b.c'
		# 以字符串形式导入
		res = importlib.import_module(module_path)
		print(res)

结果如下图所示,打印的结果和普通导入的一致

在这里插入图片描述

俩者区别

1. 普通导入方式可以导入文件中指定的对象,如下所示
		from b.c import name
		print(name)

2. 而字符串的方式最小导入单位是模块文件级别,如下示例的情况会报错

		import importlib
		
		module_path = 'b.c.name'
		res = importlib.import_module(module_path)
		print(name)

3. 功能的插拔式设计

用打印信息功能作为案例来比较,首先先使用普通函数的形式。

普通编写方式

在这里插入图片描述

在这里插入图片描述

在这种情况下,将功能封装到函数里,若是不想某单个函数执行直接在总函数里删除即可。

封装成配置

类似于settings文件的格式,封装成配置

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1. 首先创建一个包,在包中创建多个py文件,每个py文件中均有一个类,类中均定义了send方法,使其符合多态性,例如
		
		class QQ(object):
		    def __init__(self):
		        pass
			# 定义send方法
		    def send(self, info):
		        print('qq', info)

2. 在settings.py文件中创建列表用于存放字符串路径,用点的方式指向最终的类,如下示例

		NOTIFY_FUNC_LIST = [
		    'notify.qq.QQ',
		    'notify.weibo.WeiBo',
		    'notify.weixin.WeiXin',
		]

3. 在notify包中的双下init文件中编写表示全部send方法的函数,如下示例

		# 导入settings文件用于获取路径字符串
		import settings
		# 使用字符串形式导入,需要导入importlib
		import importlib
		
		# 创建send的总函数
		def send_all(info):
		    # 循环获取配置文件中的字符串,格式为 'notify.qq.QQ'
		    for str_path in settings.NOTIFY_FUNC_LIST:
		        # 从右边开始切割字符串路径,并设定最大切割次数为1,切割完结果类似于 ['notify.qq', 'QQ']
		        module_str_path, class_str_name = str_path.rsplit('.', maxsplit=1)
		        # 导入切割后的字符串路径,类似于 notify.qq
		        module = importlib.import_module(module_str_path)
		        # 使用反射方法,获取模块中的类,getattr(x, 'y') 等价于 x.y
		        class_name = getattr(module, class_str_name)
		        # 实例化模块中的类
		        obj = class_name()
		        # 调用发送信息的功能,由于发送消息的方法都叫做send,所以均可以被调用
		        obj.send(info)


4. 然后还要在start.py文件中执行包中的函数,如下示例

		# 需要先导入包,相当于导入了包中的__init__.py文件
		import notify
		
		if __name__ == '__main__':
			# 执行发送消息的总方法
		    notify.send_all('你好啊')


5. 以上的步骤结束后,会执行所有在settings文件中配置好的路径中的方法,需要注意的是多态性。如果不想执行某个py
文件中的类方法时,只要在配置文件settings中删除该路径即可,这里只表达编写思想,可以使用别的案例替换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值