django之中间件
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',
]
如何自定义中间件:
1.创建存储自定义中间件代码的py文件或者目录(如果中间件很多)
2.参考自带中间件的代码编写类并继承
3.在类中编写五个可以自定义的方法
中间件之process_request
1.请求来的时候会从上往下一次经过每个注册了的中间件里面的该方法,如果没有则直接跳过
2.如果该方法自己返回了HttpResponse对象那么不再往后执行而是直接原路返回
中间件之process_response
1.响应走的时候会从下往上一次经过每一个注册了的中间件里面的该方法,如果没有则直接跳过
2.该方法两个形参request和response,形参response指代的就是后端想要返回给前端浏览器的数据,该方法必须返回该形参,也可以替换
"""
如果在执行process-request方法的时候直接返回了HttpResponse对象那么会原路放回执行process_response 不是执行所有
"""
django中间件三个了解的方法
1.process_view
路由匹配成功之后执行视图函数/类之前自动触发(顺序跟process_request一样也是从上到下的)
2.process_exception
视图函数/类执行报错自动触发(顺序同process_response一样也是从下到上的)
3.process_template_response
视图函数/类返回的HttpResponse对象含有render并且对应一个方法的时候自动触发(顺序如同process_response一样也是从下到上的)
基于django中间件的功能设计
将各个功能制作成配置文件的字符串形式
如果想拥有该功能就编写对应的字符串
如果不想有该功能则注释调对应的字符串
补充知识
如果利用字符串导入模块,需要一个内置模块 import importlib
示例展示:
import importlib
s1 = 'aaa.bbb.ccc.ddd'
res = importlib.import_module(s1) # 将字符串放入
print(res) # <module 'aaa.bbb.ccc.ddd' from 'C:\\pythonProject\\pythonProject1\\aaa\\bbb\\ccc\\ddd.py'>
from aaa.bbb.ccc import ddd
print(ddd) # <module 'aaa.bbb.ccc.ddd' from 'C:\\pythonProject\\pythonProject1\\aaa\\bbb\\ccc\\ddd.py'>
"""
我们使用字符串导入的文件跟我们使用导入模块的句式最后得出的结果是一样的,但是要注意字符串的结果最小单位只能是py文件,不能是py文件里面的变量名
"""
项目分析
模拟编写一个消息通知功能(微信、qq、邮箱)
基于django中间件的功能设计
写法之基本开放文件:
qq.py
class Qq:
def __init__(self):
pass # 每个类都要自带有自己的双下方法做前期准备
def send_msg(self, news):
print('来自qq的消息:%s' % news)
email.py
class Email:
def __init__(self):
pass # 每个类都要自带有自己的双下方法做前期准备
def send_msg(self, news):
print('来自mail的消息:%s' % news)
weixin.py
class Weixin:
def __init__(self):
pass # 每个类都要自带有自己的双下方法做前期准备
def send_msg(self, news):
print('来自weixin的消息:%s' % news)
views包里面的__init__
import settings
import importlib
def run():
for i in settings.MSGSETTING:
path_name, class_name = i.rsplit('.', maxsplit=1)
"""从右开始只切割一个. 结果就是 ['views.qqq','Qq']解压赋值"""
res = importlib.import_module(path_name)
"""用字符串的形式导入模块,拿到模块"""
class_obj = getattr(res, class_name)
"""python中一切皆对象,这句话就是从一个模块对象中拿一个名字,直接用反射"""
obj = class_obj() # 拿到类,加括号产生一个对象,直接对象点方法就可以了
obj.send_msg('圣诞节快乐')
settings文件
MSGSETTING = ['views.qqq.Qq', 字符串的路径
'views.weixin.Weixin',
'views.email.Email'
]
启动文件
import views # 导入包其实就是导入包的双下__init__文件
if __name__ == '__main__':
views.run()

浙公网安备 33010602011771号