信号机制
Django
提供信号机制,类似于在某些特定的流程中设置一系列的
HookFunction
。
具体概念一言以蔽之,用户发生某些动作后,会发送一个特定动作的信号,我们只需要为他设置回调函数即可。
举个例子,现在项目中用到了
MySQL
和
Redis
,当我们更新某张数据表记录时,希望
Redis
中也同时更新,这个时候就可以用到信号。
Model
在
Model
操作中,有以下一些信号提供:
信号 | 描述 |
---|---|
pre_init | modal执行其构造方法前,自动触发 |
post_init | modal执行其构造方法后,自动触发 |
pre_save | modal对象保存前,自动触发 |
post_save | modal对象保存后,自动触发 |
pre_delete | modal对象删除前,自动触发 |
post_delete | modal对象删除后,自动触发 |
m2m_changed | modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发 |
class_prepared | 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发 |
connection_created | 创建数据库链接时,自动触发 |
pre_migrate | 执行migrate命令前,自动触发 |
post_migrate | 执行migrate命令后,自动触发 |
导入
Model
相关的信号:
from django.db.models.signals import class_preparedfrom django.db.models.signals import pre_init, post_initfrom django.db.models.signals import pre_save, post_savefrom django.db.models.signals56cimport pre_delete, post_deletefrom django.db.models.signals import m2m_changedfrom django.db.models.signals import pre_migrate, post_migrate
Request/Response
在请求和响应中,有下面的一些信号:
信号 | 描述 |
---|---|
request_started | 请求到来前,自动触发 |
request_finished | 请求结束后,自动触发 |
got_request_exception | 求异常后,自动触发 |
值得一提的是,
request/response
信号相比于中间件来说,并不具备拦截功能。
from django.core.signals import request_finishedfrom django.core.signals import request_startedfrom django.core.signals import got_request_exception
Test
使用测试模式进行调试时,信号如下:
信号 | 描述 |
---|---|
setting_changed | 使用test测试修改配置文件时,自动触发 |
template_rendered | 使用test测试渲染模板时,自动触发 |
导入信号:
from django.test.signals import setting_changedfrom django.test.signals import template_rendered
DB
在
DB
相关中,只有一个信号:
信号 | 描述 |
---|---|
connection_created | 创建数据库连接时,自动触发 |
使用信号
只需要在项目全局文件夹下的
__init__
里注册信号即可,注册方式有两种:
# 项目全局文件夹/__init__.pyfrom django.dispatch import receiverfrom django.db.models.signals import post_save@receiver(post_save)def callback(sender,**kwargs):\"\"\":param sender: 本次操作的class:param kwargs: 参数:return:\"\"\"print(sender)print(kwargs)上面的注册方式更为推荐,或者你也可以使用比较笨的办法:
# 项目全局文件夹/__init__.pyfrom django.db.models.signals import post_savedef callback(sender,**kwargs):\"\"\":param sender: 本次发送信号的信号源:param kwargs: 参数:return:\"\"\"print(sender)print(kwargs)post_save.connect(callback)执行结果如下:
\"\"\"<class \'app01.models.User\'>{\'signal\': <django.db.models.signals.ModelSignal object at 0x0000015230B6C2B0>, \'instance\': <User: User object (3)>, \'created\': True, \'update_fields\':ad1None, \'raw\': False, \'using\': \'default\'}\"\"\"自定义信号
Django内置信号是在特定地点自动发送信号,我们只需要设置回调即可,但是如果是自定义信号则需要我们自己定义信号、发送信号、接收信号。
首先创建一个
py文件,用于存放创建的信号:
# app01/common_signals.pyimport django.dispatch# 定义信号first_signal = django.dispatch.Signal(providing_args=[\'params_001\', \'params_002\'])然后需要设置回调该信号的函数:
# 项目全局文件夹/__init__.pyfrom app01.common_signals import first_signalfrom django.dispatch import receiver@receiver(first_signal)def callback(sender,**kwargs):\"\"\":param sender: 本次发送信号的信号源:param kwargs: 参数:return:\"\"\"print(sender)print(kwargs)最后是使用信号:
# app01/views.pyfrom django.shortcuts import HttpResponsefrom .common_signals import first_signalimport sys # 获取函数名def add(request):first_signal.send(sender=sys._getframe().f_code.co_name,params_001=\"参数1\",params_002=\"参数2\")return HttpResponse(\"ok\")执行结果如下:
\"\"\"add{\'signal\': <django.dispatch.dispatcher.Signal object at 0x000001F3508E9710>, \'params_001\': \'参数1\', \'params_002\': \'参数2\'}\"\"\"