需要借助于一个专门的装饰器模块
from django.utils.decorators import method_decorator
方式1
直接在类中的某个方法上添加
class MyLoginView(views.View): @method_decorator(login_auth) def get(self, request): return HttpResponse("from CBV get view")
方式2
直接在类名上添加并指定
@method_decorator(login_auth, name='get') class MyLoginView(views.View): def get(self, request): return HttpResponse("from CBV get view")
方式3
重写dispatch方法并添加作用于类中所有的方法
class MyLoginView(views.View): @method_decorator(login_auth) def dispatch(self, request, *args, **kwargs): super().dispatch(request,*args,**kwargs)
是django的门户,自带七个中间件,每个都有各自对应的功能,在settings.py中
自定义中间件
自定义方法
django不单有七个中间件并且每个都有很多功能和方法,除此之外django还支持自定义中间件并提供五个可以自定义的方法:
- process_request
- process_response
- process_view
- process_template_response
- process_excepton
使用场景
只要是全局相关的功能都可以在中间件中编写,比如户黑名单校验、用户访问频率校验、网站全局用户身份校验
自定义中间件步骤
- 创建一个任意名称的文件夹
- 在该文件夹内创建一个任意名称的py文件
- 在该py文件内编写中间件类
from django.utils.deprecation import MiddlewareMixin class MyMiddle1(MiddlewareMixin): def process_request(self, request): print('自定义中间件:from MyMiddle1 process_request') class MyMiddle2(MiddlewareMixin): def process_request(self, request): print('自定义中间件:from MyMiddle2 process_request')
- 配置文件中注册
'app01.mymiddleware.mymiddle.MyMiddle1', 'app01.mymiddleware.mymiddle.MyMiddle2'
自定义中间件方法
process_request
请求来的时候会从上往下依次执行配置文件中注册了的中间件里面的process_request方法,如果没有则直接跳过
如果该方法自己返回了HttpResponse对象,那么请求不再继续往后直接返回相应的数据
process_response
响应走的时候会从下往上依次执行配置文件中注册了的中间件里面的process_response方法,如果没有则直接跳过
如果该方法自己返回了HttpResponse对象,那么响应会替换成该HttpResponse对象数据,而不再是视图函数想要返回给客户端的数据
注意
如果process_request返回了HttpResponse对象 那么会从当前位置从下往上执行每一个process_response
process_view
路由匹配成功之后执行视图之前从上往下执行配置文件中注册了的中间件里面的process_view方法
process_template_response
视图函数执行完毕之后返回的对象中含有render属性对应一个render方法则会从下往上执行配置文件中注册了的中间件里面的process_template_response方法
process_exception
视图函数执行过程中报错并在返回响应的时候会从下往上执行配置文件中注册了的中间件里的process_exception方法
from ccc import b print(b) # <module 'ccc.b' from '/Users/jiboyuan/PycharmProjects/day61_1/ccc/b.py'> print(b.name)
字符串导入方式
import importlib module_path = 'ccc.b' res = importlib.import_module(module_path) print(res.name)
注意
mport importlib module_path = 'ccc.b.name' importlib.import_module(module_path) # 不可以
importlib模块最小导入单位是模块文件级别
以发送提示信息为需求编写功能
方式1:封装成函数
notify.py def send_email(msg): print('邮箱信息提示:%s' % msg) def send_msg(msg): print('短信信息提示:%s' % msg) def send_qq(msg): print('QQ信息提示:%s' % msg) def send_all(msg): send_email(msg) send_msg(msg) send_qq(msg)
start.py from notify import send_all send_all('hello world') 邮箱信息提示:hello world 短信信息提示:hello world QQ信息提示:hello world
方式2:封装成配置
emsil.py class Email(object): def __init__(self): pass def send(self, msg): print('邮箱信息提示:%s' % msg) msg.py class Msg(object): def __init__(self): pass def send(self, msg): print('短信信息提示:%s' % msg) qq.py class QQ(object): def __init__(self): pass def send(self, msg): print('QQ信息提示:%s' % msg)
settings.py NOTIFY_FUNC_LIST = [ 'notify.email.Email', 'notify.msg.Msg', 'notify.qq.QQ' ]
__init__.py import settings import importlib def send_all(msg): # 1.循环获取配置文件中字符串信息 for str_path in settings.NOTIFY_FUNC_LIST: # 'notify.email.Email' # 2.切割路径信息 module_path, class_str_name = str_path.rsplit('.', maxsplit=1) # ['notify.email','Email'] # 3.根据module_path导入模块文件 module = importlib.import_module(module_path) # 4.利用反射获取模块文件中对应的类名 class_name = getattr(module, class_str_name) # Email Msg QQ # 5.实例化 obj = class_name() # 6.调用发送消息的功能 obj.send(msg)
start.py import notify if __name__ == '__main__': notify.send_all(msg)
如果还需要取消其中某个功能,直接在配置文件注释功能的这一行即可
增加功能参考以上代码
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django中间件 - Python技术站