【Django杂记】 Django Signals信号的使用
1、信号有哪些
- Model_Signals
- pre_init:Django中的model对象执行其构造方法前,自动触发
- post_init:Django中的model对象执行其构造方法后,自动触发
- pre_save:Django中的model对象保存前,自动触发
- post_save:Django中的model对象保存后,自动触发
- pre_delete:Django中的model对象删除前,自动触发
- post_delete:Django中的model对象删除后,自动触发
- m2m_changed:Django中的model对象使用m2m字段操作数据库的第三张表(add,remove,clear,update),自动触发
- class_prepared:程序启动时,检测到已注册的model类,对于每一个类,自动触发
- Managemeng_sinals
- pre_migrate:执行migrate命令前,自动触发
- post_migrate:执行migrate命令后,自动触发
- Request/Response_signals
- request_started:请求到来前,自动触发
- request_finished:请求结束后,自动触发
- got_request_exception:请求异常时,自动触发
- Test_signals
- setting_changed:配置文件改变时,自动触发
- template_rendered:模型执行渲染操作时,自动触发
- Database_Wrapperd
- connection_created:创建数据库连接时,自动触发
2、内置信号如何使用呢?
- 场景:
- 有如下场景,我有一个Model名为Alert,表示一条告警,我需要在创建一个告警后进行邮件通知,怎么实现呢?
- 常规实现:
- Alert类加一个表示字段is_notify表示是否通过过,然后创建一个command,在后台定时读取Alert里未通知的记录:
for alert in Alert.objects.filter(is_notify = False):
# 发邮件
alert.is_notify = True
- 缺点:
- 需要创建一个后台进程
- 需要增加一个字段标识是否通过
- 后台进程的维护,如挂掉了,那么邮件通知不就终止了...
- 使用信号呢?
@receiver(post_save, sender=Alert)
def alert_notify(sender, instance, created, **kwargs):
if created:
# 发送邮件
return
- 使用的方法:
- 1、在自己的应用app下的init.py文件中:[假设我有一个名为tongjiapp的应用]
default_app_config = "tongjiapp.apps.TongjiappConfig"
- 2、在自己应用的app下的apps.py文件中:
from django.apps import AppConfig
class TongjiappConfig(Appconfig):
name = "tongjiapp"
def ready(self):
# 导入信号py文件
import tongjiapp.signals.async_script_signals
- 3、在async_script_sinals中代码如下:
from django.db.models.signals import post_migrate
from django.dispatch import receiver
@receiver(post_migrate)
def init_script(sender, **keargs):
print("我执行了")
# 操作

3、信号参数
- pre_init
- django.db.models.signals.pre_init
- 每当你实例化Django模型时,该信号都会在模型的__init__()方法的开头发送
- 参数:
- sender:刚创建了一个实例的模型类
- args:传递给__init__()的位置参数列表
- kwargs:传递给__init__()的关键字参数的字典
- pre_save
- django.db.models.signals.pre_save
- 这是在模型的save()方法的开头发送的
- 参数:
- sender:模型类
- instance:正在保存的实际实例
- raw:一个布尔值True,如果模型按照显示的方式保存(即当加载固定装置时);不应该查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态。
- using:正在使用的数据库别名
- update_fields:如果有字段被传递给Model.save()方法,那么就是所传递的字段集,否则就是None
- post_save
- django.db.models.signals.post_save
- 像pre_save一样,但是在save()方法的末尾发送
- 参数:
- sender:模型类
- instance:正在保存的实际实例
- created:一个布尔值,True如果创建新记录
- raw:一个布尔值True,如果模型按照显示的方式保存(即当加载固定装置时);不应该查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态
- using:正在使用的数据库别名
- update_fields:如果有字段被传递给Model.save()方法,那么就是所传递的字段集,否则就是None
- pre_delete
- django.db.models.signals.pre_delete
- 在模型的delete()方法和queryset的delete()方法的开头发送
- 参数:
- sender:模型类
- instance:正在删除的实际实例
- using:正在使用的数据库别名
- post_delete
- django.db.models.signals.post_delete
- 像pre_delete一样,但是在模型的delete()方法和queryset的delete()方法的末尾发送
- 参数:
- sender:模型类
- instance:正在删除的实际实例
- 注意:该对象将不再位于数据库中,所以要非常小心使用此实例
- using:正在使用的数据库别名
- m2m_changed
- django.db.models.signals.m2m_changed
- 在模型实例上更改了ManyToManyField时发送。严格来说,这不是一个模型信号,因为它是由ManyToManyField发送的,但由于它补充了pre_save/post_save和pre_delete/post_delete当跟踪模型更改时,它包括在这里。
- 参数:
- sender:描述ManyToManyField的中间模型类。 当定义多对多字段时,此类自动创建;您可以使用多对多字段上的through属性访问它。
- instance:多对多关系更新的实例。 这可以是sender或ManyToManyField相关的类的一个实例。
- action:指示在关系上完成的更新类型的字符串。 这可以是以下之一
- pre_add:在之前发送一个或多个对象被添加到关系中。
- post_add:在之后发送一个或多个对象被添加到关系中。
- pre_remove:在之前发送一个或多个对象从关系中删除。
- post_remove:在之后发送一个或多个对象从关系中删除。
- pre_clear:在之前发送关系被清除。
- post_clear:之后发送关系被清除。
- reverse:指示关系的哪一侧被更新(即,如果它是正在被修改的正向或反向关系)。
- model:从关系中删除或从关系中清除的对象的类。
- pk_set:对于pre_add,post_add,pre_remove和post_remove操作,这是一组主键值加入或从关系中删除。
- 对于pre_clear和post_clear操作,这是None。
- using:正在使用的数据库别名
- class_prepared
- django.db.models.signals.class_prepared
- 每当模型类"准备"时发送,即一旦模型已经被定义并在Django的模型系统中注册。Django内部使用这个信号;它通常不会用于第三方应用程序。
- 由于此信号是在应用程序注册表群集进程期间发送的,并且在应用注册表完全填充后运行AppConfig.ready(),因此无法使用该方法连接接收器。一种可能性是连接他们AppConfig.__init__(),注意不要导入模型或触发对应用程序注册表的调用
- 参数:
- send:ready的model类
管理信号:
- pre_migrate
- django.db.models.signals.pre_migrate
- 在开始安装应用程序之前,有migrate命令发送。对于缺少models模块的应用,不会发送。
- 参数:
- sender:应用程序即将迁移/同步的AppConfig实例
- APP_CONFIG:与sender相同
- verbosity:指示manage.py在屏幕上打印多少信息。有关详细信息,请参阅--verbosity标志。监听pre_migrate的函数应根据该参数的值调整输出到屏幕的内容
- interactive:如果interactive是True,则可以安全地提示用户在命令行中输入内容。如果interactive为False,则侦听此信号的功能不应尝试提示任何内容。
- 例如:当interactive为True时,django.contrib.auth应用程序仅提示创建超级用户
- using:命令将在其上运行的数据库的别名
- plan:迁移计划将用于迁移运行,虽然该计划不是公共API,但这在允许罕见的情况下需要知道计划。一个计划是两个元组的列表,第一个项目时迁移类的实例,第二个项目显示迁移是否回滚(True)或应用(False)
- apps:django中的新功能1.10。包含迁移运行前的项目状态的Apps的实例。应该使用它来代替全局apps注册表来检索要执行操作的模型。
- post_migrate
- django.db.models.signals.post_migrate
- 在migrate(即使不进行迁移)和flush命令的末尾发送。对于缺少models模块的应用,不会发送。
- 注意:此信号的处理程序不得执行数据库模式更改,因为如果在migrate命令期间运行,则可能会导致flush命令失败。
- 参数:
- sender:刚刚安装的应用程序的AppConfig实例
- APP_CONFIG:与sender相同
- verbosity:指示manage.py在屏幕上打印多少信息。有关详细信息,请参阅--verbosity标志。监听post_migrate的函数应根据该参数的值调整输出到屏幕的内容
- interactive:如果interactive是True,则可以安全地提示用户在命令行中输入内容。如果interactive为False,则侦听此信号的功能不应尝试提示任何内容。
- 例如:当interactive为True时,django.contrib.auth应用程序仅提示创建超级用户
- using:用于同步的数据库别名。默认为default数据库
- plan:迁移计划将用于迁移运行,虽然该计划不是公共API,但这在允许罕见的情况下需要知道计划。一个计划是两个元组的列表,第一个项目时迁移类的实例,第二个项目显示迁移是否回滚(True)或应用(False)
- apps:django中的新功能1.10。包含迁移运行前的项目状态的Apps的实例。应该使用它来代替全局apps注册表来检索要执行操作的模型。
请求/响应信号
- 处理请求时由核心框架发送的信号
- request_started
- django.core.signals.request_started
- 当Django开始处理http请求时发送
- 参数:
- sender:处理程序类;例如django.core.handlers.wsgi.WsgiHandler:处理该请求
- ENVIRON:environ字典提供给请求
- request_finished
- django.core.signals.request_finished
- 当Django完成向客户端传递HTTP响应时发送
- 参数:
- sender:处理程序类,如上。
- got_request_exception
- django.core.signals.got_request_exception
- 当Django在处理传入的HTTP请求时遇到异常时,会发送此信号
- 参数:
- sender:处理程序类,如上。
- request:HttpRequest对象
测试信号
- 信号只在runing tests时发送
- setting_changed
- django.test.signals.setting_changed
- 当通过django.test.TestCase.settings()上下文管理器或django.test.override_settings()装饰器/上下文管理器
- 实际发送两次:应用新值("setup")和恢复原始值("拆除")时。使用enter参数来区分两者。你还可以从django.core.signals导入此信号,以避免在非测试情况下从django.test导入。
- 参数:
- sender:设置处理程序
- setting:设置的名称
- value:更改后的设置值。对于最初不存在的设置,在"拆除"阶段,value为None
- enter:一个布尔值,True如果应用设置,False如果还原
- template_rendered
- django.test.signals.template_rendered
- 测试系统呈现模板时发送。在Django服务器的正常操作期间不发出此信号,它仅在测试期间可用。
- 参数:
- sender:被渲染的Template对象
- template:与发信人相同
- context:模板呈现的Context
数据库包装器
- 当数据库连接启动时,由数据库包装器发送的信号。
- connection_created
- django.db.backends.signals.connection_created
- 当数据库包装器与数据库进行初始连接时发送。如果你想将任何后续连接命令发送到SQL后端,这一点尤其有用。
- 参数:
- sender:数据库包装器类:即django.db.backends.postgresql.DatabaseWrapper或django.db.backends.mysql.DatabaseWrapper等
- connection:打开的数据库连接。这可以在多数据库配置中使用,以区分来自不同数据库的连接信号。
本文来自博客园,作者:郭祺迦,转载请注明原文链接:https://www.cnblogs.com/guojie-guojie/p/16330173.html