信号 — Django 文档

来自菜鸟教程
Django/docs/3.2.x/ref/signals
跳转至:导航、​搜索

信号

Django 发送的所有信号的列表。 所有内置信号都使用 send() 方法发送。

也可以看看

有关如何注册和接收信号的信息,请参阅 信号调度程序 上的文档。

认证框架在用户登录/注销时发送信号。


模型信号

django.db.models.signals 模块定义了模型系统发送的一组信号。

警告

其中许多信号是由各种模型方法发送的,例如 __init__() 或 save(),您可以在自己的代码中覆盖这些方法。

如果您在模型上覆盖这些方法,则必须调用父类的方法来发送这些信号。

另请注意,Django 默认将信号处理程序存储为弱引用,因此如果您的处理程序是本地函数,则它可能会被垃圾收集。 为了防止这种情况,在调用信号的 connect() 时传递 weak=False。


笔记

模型信号 sender 模型可以在连接接收器时通过指定其完整的应用程序标签来延迟引用。 例如,在 polls 应用程序中定义的 Question 模型可以被引用为 'polls.Question'。 在处理循环导入依赖项和可交换模型时,这种参考非常方便。


pre_init

django.db.models.signals.pre_init

每当您实例化 Django 模型时,该信号都会在模型的 __init__() 方法的开头发送。

与此信号一起发送的参数:

sender
刚刚创建了一个实例的模型类。
args
传递给 __init__() 的位置参数列表。
kwargs
传递给 __init__() 的关键字参数字典。

例如,tutorial 有这样一行:

q = Question(question_text="What's new?", pub_date=timezone.now())

发送到 pre_init 处理程序的参数将是:

论据 价值
sender Question(类本身)
args [](一个空列表,因为没有传递给 __init__() 的位置参数)
kwargs {'question_text': "What's new?",

'pub_date': datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)}


post_init

django.db.models.signals.post_init

与 pre_init 类似,但在 __init__() 方法完成时发送这个。

与此信号一起发送的参数:

sender

如上:刚刚创建了一个实例的模型类。

instance

刚刚创建的模型的实际实例。

笔记

instance._state 在发送 post_init 信号之前没有设置,所以 _state 属性总是有它们的默认值。 例如,_state.db 是 None。

警告

出于性能原因,您不应在 pre_init 或 post_init 信号的接收器中执行查询,因为它们将针对查询集迭代期间返回的每个实例执行。


pre_save

django.db.models.signals.pre_save

这是在模型的 save() 方法的开头发送的。

与此信号一起发送的参数:

sender
模型类。
instance
正在保存的实际实例。
raw
一个布尔值; True 如果模型完全按照显示保存(即 加载夹具时)。 不应查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态。
using
正在使用的数据库别名。
update_fields
传递给 Model.save() 或 None(如果 update_fields 未传递给 save())的字段集。


post_save

django.db.models.signals.post_save

类似于 pre_save,但在 save() 方法的末尾发送。

与此信号一起发送的参数:

sender
模型类。
instance
正在保存的实际实例。
created
一个布尔值; True 如果创建了新记录。
raw
一个布尔值; True 如果模型完全按照显示保存(即 加载夹具时)。 不应查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态。
using
正在使用的数据库别名。
update_fields
传递给 Model.save() 或 None(如果 update_fields 未传递给 save())的字段集。


pre_delete

django.db.models.signals.pre_delete

在模型的 delete() 方法和查询集的 delete() 方法的开头发送。

与此信号一起发送的参数:

sender
模型类。
instance
被删除的实际实例。
using
正在使用的数据库别名。


post_delete

django.db.models.signals.post_delete

类似于 pre_delete,但在模型的 delete() 方法和查询集的 delete() 方法的末尾发送。

与此信号一起发送的参数:

sender

模型类。

instance

被删除的实际实例。

请注意,该对象将不再存在于数据库中,因此在处理此实例时要非常小心。

using

正在使用的数据库别名。


m2m_changed

django.db.models.signals.m2m_changed

在模型实例上更改 ManyToManyField 时发送。 严格来说,这不是模型信号,因为它是由 ManyToManyField 发送的,但因为它补充了 pre_save/post_save 和 pre_delete[X18] ]/post_delete 当涉及到跟踪模型的更改时,它包含在这里。

与此信号一起发送的参数:

sender

描述 ManyToManyField 的中间模型类。 定义多对多字段时会自动创建此类; 您可以使用多对多字段上的 through 属性访问它。

instance

多对多关系被更新的实例。 这可以是 sender 的实例,或 ManyToManyField 相关的类的实例。

action

指示对关系进行的更新类型的字符串。 这可以是以下之一:

"pre_add"

Sent before 一个或多个对象被添加到关系中。

"post_add"

在 一个或多个对象添加到关系后发送 。

"pre_remove"

Sent before 一个或多个对象从关系中移除。

"post_remove"

在 一个或多个对象从关系中移除后发送 。

"pre_clear"

发送 before 关系被清除。

"post_clear"

在 关系被清除后发送 。

reverse

指示更新关系的哪一侧(即,正在修改的是正向关系还是反向关系)。

model

添加到关系中、从关系中删除或从关系中清除的对象的类。

pk_set

对于 pre_add 和 post_add 操作,这是一组将要或已经添加到关系中的主键值。 这可能是提交要添加的值的子集,因为插入必须过滤现有值以避免数据库 IntegrityError。

对于 pre_remove 和 post_remove 操作,这是一组提交以从关系中删除的主键值。 这不取决于这些值是否实际将被删除或已经被删除。 特别是,不存在的值可能会被提交,并且会出现在 pk_set 中,即使它们对数据库没有影响。

对于 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

在开始安装应用程序之前由 :djadmin:`migrate` 命令发送。 对于缺少 models 模块的应用程序,它不会发出。

与此信号一起发送的参数:

sender

即将迁移/同步的应用程序的 AppConfig 实例。

app_config

与 sender 相同。

verbosity

指示 manage.py 在屏幕上打印的信息量。 有关详细信息,请参阅 --verbosity 标志。

侦听 pre_migrate 的函数应根据此参数的值调整它们输出到屏幕的内容。

interactive

如果 interactive 是 True,提示用户在命令行输入内容是安全的。 如果 interactive 是 False,则监听此信号的函数不应尝试提示任何内容。

例如,django.contrib.auth 应用仅在 interactive 为 True 时才提示创建超级用户。

using

命令将在其上运行的数据库的别名。

plan

将用于迁移运行的迁移计划。 虽然该计划不是公共 API,但在极少数情况下需要了解该计划。 计划是一个双元组列表,第一项是迁移类的实例,第二项显示迁移是回滚 (True) 还是应用 (False)。

apps

Apps 的一个实例,包含迁移运行前的项目状态。 应该使用它而不是全局 apps 注册表来检索要对其执行操作的模型。


post_migrate

django.db.models.signals.post_migrate

在 :djadmin:`migrate`(即使没有运行迁移)和 :djadmin:`flush` 命令的末尾发送。 对于缺少 models 模块的应用程序,它不会发出。

此信号的处理程序不得执行数据库模式更改,因为如果在 :djadmin:`migrate` 命令期间运行,这样做可能会导致 :djadmin:`flush` 命令失败。

与此信号一起发送的参数:

sender

刚安装的应用程序的 AppConfig 实例。

app_config

与 sender 相同。

verbosity

指示 manage.py 在屏幕上打印的信息量。 有关详细信息,请参阅 --verbosity 标志。

侦听 post_migrate 的函数应根据此参数的值调整它们输出到屏幕的内容。

interactive

如果 interactive 是 True,提示用户在命令行输入内容是安全的。 如果 interactive 是 False,则监听此信号的函数不应尝试提示任何内容。

例如,django.contrib.auth 应用仅在 interactive 为 True 时才提示创建超级用户。

using

用于同步的数据库别名。 默认为 default 数据库。

plan

用于迁移运行的迁移计划。 虽然该计划不是公共 API,但在极少数情况下需要了解该计划。 计划是一个双元组列表,第一项是迁移类的实例,第二项显示迁移是回滚 (True) 还是应用 (False)。

apps

Apps 的一个实例,包含迁移运行后的项目状态。 应该使用它而不是全局 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 实例作为发送方参数,请确保信号已在 ready() 中注册。 AppConfig 是为使用一组修改后的 :setting:`INSTALLED_APPS`(例如当设置被覆盖时)运行的测试重新创建的,并且应该为每个新的 AppConfig 实例。


请求/响应信号

处理请求时由核心框架发送的信号。

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
未使用(总是 None)。
request
HttpRequest 对象。


测试信号

仅在 运行测试 时发送信号。

setting_changed

django.test.signals.setting_changed

当设置的值通过 django.test.TestCase.settings() 上下文管理器或 django.test.override_settings() 装饰器/上下文管理器更改时发送此信号。

它实际上发送了两次:应用新值时(“设置”)和恢复原始值时(“拆卸”)。 使用 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
已打开的数据库连接。 这可用于多数据库配置以区分来自不同数据库的连接信号。