Django发送的所有信号. 所有内置信号都是通过 send() 方法发送.
django.db.models.signals 模块定义了一系列由模型系统发送的信号.
警告
很多信号是通过模型方法如
__init__() 或者 save() 发送的, 你可以在代码中重写这一行为.
如果你在模型中重写了这些方法, 则必须调用父类的方法才能发送这些信号.
还需要注意的是, 信号处理程序在Django中默认为弱引用, 所以如果你的处理程序是一个本地函数, 它可能会被垃圾回收.
为了防止这种情况, 在你调用信号的 connect() 时, 传入 weak=False.
注解
连接接收器时通过指定其完整的应用标签, 延迟引用模型信号 sender 模型. 例如, polls 应用程序中定义的 Answer 模型可以通过 'polls.Answer' 引用.
这在处理循环导入依赖和可交换模型时非常方便.
pre_init¶django.db.models.signals.pre_init¶每当实例化Django模型时, 该信号都会在模型的 __init__() 方法之前发出.
该信号发送的参数有:
senderargs__init__() 中的位置参数列表:kwargs__init__() 中的关键字参数的字典:例如, 在 教程 中有这样一行:
p = Poll(question="What's up?", pub_date=datetime.now())
发送给 pre_init 处理程序的参数是:
| 参数 | 值 |
|---|---|
sender |
Poll (类本身) |
args |
[] (空列表, 因为 __init__() 中没有传入位置参数.) |
kwargs |
{'question': "What's up?", 'pub_date': datetime.now()} |
post_init¶django.db.models.signals.post_init¶类似pre_init, 在 __init__() 方法完成后发出的信号.
该信号发送的参数有:
senderinstancepre_save¶django.db.models.signals.pre_save¶在模型的 save() 方法开始时发出的信号.
该信号发送的参数有:
senderinstancerawTrue. 不应查询和修改数据库中的其他记录, 因为数据库中可能尚未处于一致状态.usingupdate_fieldsModel.save() 方法的要更新的字段集,
如果 save() 没有传递 update_fields 参数则为 None.post_save¶django.db.models.signals.post_save¶类似 pre_save, 在模型
save() 方法结束后发送的信号.
该信号发送的参数有:
senderinstancecreatedTrue.rawTrue. 不应查询和修改数据库中的其他记录, 因为数据库中可能尚未处于一致状态.usingupdate_fieldsModel.save() 方法的要更新的字段集,
如果 save() 没有传递 update_fields 参数则为 None.pre_delete¶django.db.models.signals.pre_delete¶在模型的 delete() 方法 和
查询集的 delete() 方法开始时发送的信号.
该信号发送的参数有:
senderinstanceusingpost_delete¶django.db.models.signals.post_delete¶类似 pre_delete, 在模型的
delete() 方法和查询集的
delete() 方法结束后发送的信号.
该信号发送的参数有:
senderinstance被删除的模型实例.
注意,该对象已经不存在于数据库中, 处理这个实例时要小心这一点.
usingm2m_changed¶django.db.models.signals.m2m_changed¶模型实例的 ManyToManyField 改变时发出的信号.
严格的讲, 它不是一个模型信号, 因为它是由
ManyToManyField 发出, 但是由于当涉及到跟踪模型的变化时, 它是对
pre_save/post_save 和 pre_delete/post_delete 的补充,
所以它被放到了这里.
该信号发送的参数有:
senderManyToManyField 的中间类. 在定义了多对多关系时会自动创建这个类;
可以通过多对多字段的 through 属性来访问它.instancesender 实例, 或者
ManyToManyField 关联的类的实例.action表示更新类型的字符串. 可以是以下类型之一:
"pre_add""post_add""pre_remove""post_remove""pre_clear""post_clear"reversemodelpk_set对于 pre_add, post_add, pre_remove 和 post_remove 动作,
它是被添加或移除关联的主键值的集合.
对于 pre_clear 和 post_clear 动作, 该值为 None.
using举个例子, 假如 Pizza 有多个 Topping 对象, 模型如下:
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)
如果连接一个这样的处理程序:
from django.db.models.signals import m2m_changed
def toppings_changed(sender, **kwargs):
# Do something
pass
m2m_changed.connect(toppings_changed, sender=Pizza.toppings.through)
然后做了这样的操作:
>>> p = Pizza.objects.create(...)
>>> t = Topping.objects.create(...)
>>> p.toppings.add(t)
那么发送给 m2m_changed 处理程序(上面例子中的 toppings_changed)的参数将是:
| 参数 | 值 |
|---|---|
sender |
Pizza.toppings.through (m2m的中间类) |
instance |
p (被修改 Pizza 实例) |
action |
"pre_add" (之后是 "post_add" 信号) |
reverse |
False (Pizza 包含
ManyToManyField, 所以这个调用是更新正向关系) |
model |
Topping (添加到 Pizza 的对象) |
pk_set |
{t.id} (因为只有 Topping t 被添加到关联中) |
using |
"default" (使用默认值) |
如果再做这样的操作:
>>> t.pizza_set.remove(p)
那么发送给 m2m_changed 处理程序的参数将是:
| 参数 | 值 |
|---|---|
sender |
Pizza.toppings.through (m2m的中间类) |
instance |
t (被修改的 Topping 实例) |
action |
"pre_remove" (之后是 "post_remove" 信号) |
reverse |
True (Pizza 包含
ManyToManyField, 所以这个调用是更新反向关系) |
model |
Pizza (从 Topping 中移除的对象) |
pk_set |
{p.id} (因为只删除 Pizza p 的关联) |
using |
"default" (使用默认值) |
class_prepared¶django.db.models.signals.class_prepared¶当“准备好”一个模型类 —— 即模型被定义好并在Django的模型系统中注册时, 就会发出这个信号. 这是Django内部使用的信号, 第三方应用中一般不使用.
由于这个信号是在应用注册表填充期间中发出的, 而 AppConfig.ready() 是在应用注册表完全填充后运行的,
所以不能在该方法中连接接收器. 一种方法是用 AppConfig.__init__() 来代替连接它们, 注意不要导入模型或触发对应用注册表的调用.
该信号发送的参数有:
sender由 django-admin 发出的信号.
pre_migrate¶django.db.models.signals.pre_migrate¶在 migrate 命令安装应用之前发出的信号. 没有 models 模块的应用不会发出此信号.
该信号发送的参数有:
senderAppConfig 实例.app_configsender.verbosity表示manage.py打印到屏幕上的信息量. 详见 --verbosity.
监听 pre_migrate 的函数应该根据这个参数的值来调整它们向屏幕输出的内容.
interactive如果 interactive 为 True, 则可以安全地提示用户在命令行上输入东西. 如果 interactive 为 False, 则监听该信号的函数不应提示任何内容.
例如 django.contrib.auth 应用只有在 interactive 为 True 时才会提示创建超级用户.
usingplan用于运行迁移的迁移计划. 迁移计划不是公开的API, 但在极少数情况下有必要知道计划.
计划是一个由二元元组组成的列表, 第一项是迁移类的实例, 第二项显示迁移是否被回滚(True)或应用(False).
appspost_migrate¶django.db.models.signals.post_migrate¶在 migrate (即使没有运行迁移) 和 flush 命令结束之后发出的信号. 没有 models 模块的应用不会发出此信号.
该信号的处理者不得更改数据库模式, 因为如果在 migrate 命令期间运行 flush 命令, 则可能会导致 flush 命令失败.
该信号发送的参数有:
senderAppConfig 实例.app_configsender.verbosity表示manage.py打印到屏幕上的信息量. 详见 --verbosity.
监听 pre_migrate 的函数应该根据这个参数的值来调整它们向屏幕输出的内容.
interactive如果 interactive 为 True, 则可以安全地提示用户在命令行上输入东西. 如果 interactive 为 False, 则监听该信号的函数不应提示任何内容.
例如 django.contrib.auth 应用只有在 interactive 为 True 时才会提示创建超级用户.
usingdefault 数据库.plan用于运行迁移的迁移计划. 迁移计划不是公开的API, 但在极少数情况下有必要知道计划.
计划是一个由二元元组组成的列表, 第一项是迁移类的实例, 第二项显示迁移是否被回滚(True)或应用(False).
apps举个例子, 在
AppConfig 中注册一个回调:
from django.apps import AppConfig
from django.db.models.signals import post_migrate
def my_callback(sender, **kwargs):
# Your specific logic here
pass
class MyAppConfig(AppConfig):
...
def ready(self):
post_migrate.connect(my_callback, sender=self)
注解
如果你使用了 AppConfig 实例作为sender的参数, 请确保该信号注册在
ready() 中.
使用修改过的 INSTALLED_APPS (例如当配置被修改时)集合运行测试时,
AppConfig 会被重新创建, 这种信号应该为每个新的 AppConfig 实例连接e.
核心框架处理请求时发出的信号.
request_started¶django.core.signals.request_started¶HTTP请求在开始被处理时发送的信号.
该信号发送的参数有:
senderdjango.core.handlers.wsgi.WsgiHandler – 处理该请求.environenviron 字典.request_finished¶django.core.signals.request_finished¶当Django向客户端发送HTTP响应完成时发送的信号.
注解
一些WSGI服务器和中间件在处理请求后并不总会对响应对象调用 close, 最明显的是uWSGI1.2.6之前的版本和Sentry的错误报告中间件2.0.7之前的版本.
该信号发送的参数有:
sendergot_request_exception¶django.core.signals.got_request_exception¶每当Django在处理HTTP请求遇到异常时就会发出这个信号.
该信号发送的参数有
senderrequestHttpRequest 对象.运行测试 时发出的信号.
setting_changed¶django.test.signals.setting_changed¶在使用 django.test.TestCase.settings() 上下文管理器或者
django.test.override_settings() 装饰器/上下文管理器修改配置值时发出的信号.
它实际上会发送两次: 应用新值(“setup”)和恢复原始值(“teardown”). 使用 enter 参数来区别这两种情况.
为避免在非测试情况下从 django.test 中引入, 你可以从 django.core.signals 引入该信号.
该信号发送的参数有:
sendersettingvaluevalue 为 None.enterTrue, 还原为 False.当数据库连接启动时, database wrapper发出的信号.
connection_created¶django.db.backends.signals.connection_created¶当database wrapper与数据库进行初始连接时发送的信号. 这对于向SQL后端发送连接后的命令特别有用.
该信号发送的参数有:
senderdjango.db.backends.postgresql.DatabaseWrapper 或
django.db.backends.mysql.DatabaseWrapper, 等.connection10月 29, 2021