# Django 5.2.8 documentation

# 信号

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

See also

关于如何注册和接收信号的信息，请参见 信号收发 的文档。

认证框架 在 用户登录／退出时发送信号。

## 模型信号

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

Warning

信号可以使您的代码更难维护。考虑在 自定义管理器 上实现一个辅助方法，既可以更新您的模型又可以执行其他逻辑，或者在使用模型信号之前 覆盖模型方法。

Warning

这些信号中有很多是由各种模型方法发送的，比如 `__init__()` 或 `save()`，你可以在自己的代码中覆盖这些方法。

如果你在模型上重写了这些方法，你必须调用父类的方法才能发送这些信号。

Note also that Django stores signal handlers as weak references by default, so if your handler is a local function, it may be garbage collected. To prevent this, pass `weak=False` when you call the signal's `connect()`.

Note

模型信号 `sender` 模型可以在连接接收器时，通过指定其完整的应用程序标签进行惰性引用。例如，在 `polls` 应用程序中定义的 `Question` 模型可以被引用为 `'polls.Question'`。在处理循环导入依赖关系和可交换模型时，这种引用可以非常方便。

### `pre_init`

django.db.models.signals.pre_init

每当你实例化一个 Django 模型时，这个信号都会在模型的 `__init__()` 方法的开头发出。

用此信号发送的参数：

`sender`

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

`args`

  传递给 `__init__()` 的位置参数列表。

`kwargs`

  传递给 `__init__()` 的关键字参数字典。

例如，教程 有这样一行：

    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=datetime.UTC)}`

### `post_init`

django.db.models.signals.post_init

和 pre_init 一样，但这个是在 `__init__()` 方法完成后发送的。

用此信号发送的参数：

`sender`

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

`instance`

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

  Note

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

Warning

出于性能考虑，你不应该在 `pre_init` 或 `post_init` 信号的接收者中执行查询，因为在查询集迭代期间，它们会对每个返回的实例执行。

### `pre_save`

django.db.models.signals.pre_save

这是在模型的 `save()` 方法开始时发送的。

用此信号发送的参数：

`sender`

  模型类

`instance`

  实际被保存的实例。

`raw`

  一个布尔值；如果模型被保存的方式与原始数据一致（即在加载 fixture 时），则为 `True`。在这种情况下，不应查询/修改数据库中的其他记录，因为数据库可能尚未处于一致状态。

`using`

  正在使用的数据库别名。

`update_fields`

  传递给 `Model.save()` 的要更新的字段集，如果 `update_fields` 没有传递给 `save()`，则为 `None`。

### `post_save`

django.db.models.signals.post_save

就像 `pre_save` 一样，但在 `save()` 方法的最后发送。

用此信号发送的参数：

`sender`

  模型类

`instance`

  实际被保存的实例。

`created`

  一个布尔值；`True` 如果创建了一个新记录。

`raw`

  一个布尔值；如果模型被保存的方式与原始数据一致（即在加载 fixture 时），则为 `True`。在这种情况下，不应查询/修改数据库中的其他记录，因为数据库可能尚未处于一致状态。

`using`

  正在使用的数据库别名。

`update_fields`

  传递给 `Model.save()` 的要更新的字段集，如果 `update_fields` 没有传递给 `save()`，则为 `None`。

### `pre_delete`

django.db.models.signals.pre_delete

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

用此信号发送的参数：

`sender`

  模型类

`instance`

  实际被删除的实例。

`using`

  正在使用的数据库别名。

`origin`

  The `Model` or `QuerySet` instance from which the deletion originated, that is, the instance whose `delete()` method was invoked.

### `post_delete`

django.db.models.signals.post_delete

就像 `pre_delete` 一样，但在模型的 `delete()` 方法和查询集的 `delete()` 方法结束时发送。

用此信号发送的参数：

`sender`

  模型类

`instance`

  实际被删除的实例。

  请注意，该对象将不再在数据库中，所以要非常小心地处理这个实例。

`using`

  正在使用的数据库别名。

`origin`

  The `Model` or `QuerySet` instance from which the deletion originated, that is, the instance whose `delete()` method was invoked.

### `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` 动作，这是一组将被或已经被添加到关系中的主键值。这可能是提交添加的值的一个子集，因为插入必须过滤现有的值，以避免数据库 `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

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

用此信号发送的参数：

`sender`

  一个 `AppConfig` 实例，用于即将迁移／同步的应用程序。

`app_config`

  同 `sender`。

`verbosity`

  指示 `manage.py` 在屏幕上打印多少信息。有关详细信息，请参阅 `--verbosity` 标志。

  监听 `pre_migrate` 的函数应该根据这个参数的值来调整它们向屏幕输出的内容。

`interactive`

  如果 `interactive` 为 `True`，则可以安全地提示用户在命令行上输入东西。如果 `interactive` 为 `False`，则监听该信号的函数不应试图提示任何东西。

  例如 `django.contrib.auth` 应用只有在 `interactive` 为 `True` 时才会提示创建超级用户。

`stdout`

  一个类似于流的对象，用于重定向详细的输出。

`using`

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

`plan`

  将用于迁移运行的迁移计划。虽然计划不是公共 API，但这允许在必要时了解计划的情况。计划是一个包含 2 元组的列表，第一个项目是迁移类的实例，第二个项目显示迁移是回滚（`True`）还是应用（`False`）。

`apps`

  `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`，则监听该信号的函数不应试图提示任何东西。

  例如 `django.contrib.auth` 应用只有在 `interactive` 为 `True` 时才会提示创建超级用户。

`stdout`

  一个类似于流的对象，用于重定向详细的输出。

`using`

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

`plan`

  用于迁移运行的迁移计划。尽管计划不是公共 API，但这允许在必要时了解计划的情况。计划是一个包含 2 元组的列表，第一个项目是迁移类的实例，第二个项目显示迁移是回滚（`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)

Note

如果你提供了一个 `AppConfig` 实例作为发送者参数，请确保该信号在 `ready()` 中注册。`AppConfig` 会被重新创建，用于使用修改过的 `INSTALLED_APPS` 集合运行的测试（例如当配置被覆盖时），并且这种信号应该为每个新的 `AppConfig` 实例连接。

## 请求／响应信号

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

Warning

信号可能会使您的代码更难维护。在使用请求/响应信号之前，考虑 使用中间件。

### `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()` 装饰器／上下文管理器改变配置值时，会发出这个信号。

它实际上被发送了两次：当应用新的值时（"setup"）和当恢复原始值时（"drawdown"）。使用 `enter` 参数来区分这两种情况。

你也可以从 `django.core.signals` 导入这个信号，以避免在非测试情况下从 `django.test` 导入。

用此信号发送的参数：

`sender`

  配置处理程序。

`setting`

  配置的名称。

`value`

  更改后的配置值。对于最初不存在的配置，在 "teardown" 阶段，`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

Sent when the database wrapper makes the initial connection to the database. This is particularly useful if you'd like to send any post connection commands to the SQL backend.

用此信号发送的参数：

`sender`

  数据库封装类 —— 即 `django.db.backends.postgresql.DatabaseWrapper` 或 `django.db.backends.mysql.DatabaseWrapper` 等。

`connection`

  打开的数据库连接。这在多数据库配置中可以用来区分不同数据库的连接信号。

## Tasks signals

New in Django 6.0.

Signals sent by the tasks framework.

### `task_enqueued`

django.tasks.signals.task_enqueued

Sent once a Task has been enqueued.

用此信号发送的参数：

`sender`

  The backend class which the Task was enqueued on to.

`task_result`

  The enqueued `TaskResult`.

### `task_started`

django.tasks.signals.task_started

Sent when a Task has started executing.

用此信号发送的参数：

`sender`

  The backend class which the Task was enqueued on to.

`task_result`

  The started `TaskResult`.

### `task_finished`

django.tasks.signals.task_finished

Sent once a Task has finished executing, successfully or otherwise.

用此信号发送的参数：

`sender`

  The backend class which the Task was enqueued on to.

`task_result`

  The finished `TaskResult`.