# Django 3.2.11.dev 文档

# 信号

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__()` 的关键字参数字典。

例如，教程 有这样一行：

    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()` 的要更新的字段集，如果 `update_fields` 没有传递给 `save()`，则为 `None`。

### `post_save`

`django.db.models.signals.``post_save`

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

用此信号发送的参数：

`sender`
  模型类
`instance`
  实际被保存的实例。
`created`
  一个布尔值；`True` 如果创建了一个新记录。
`raw`
  一个布尔值；`True` 如果模型完全按照显示的方式保存（即加载固定数据时）。不应该查询／修改数据库中的其他记录，因为数据库可能还没有达到一致的状态。
`using`
  正在使用的数据库别名。
`update_fields`
  传递给 `Model.save()` 的要更新的字段集，如果 `update_fields` 没有传递给 `save()`，则为 `None`。

### `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`/`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` 时才会提示创建超级用户。

`using`
  命令将运行的数据库的别名。
`plan`
  将用于迁移运行的迁移计划。虽然计划不是公开的 API，但这允许在极少数情况下有必要知道计划。计划是一个由二元元组组成的列表，第一项是迁移类的实例，第二项显示迁移是否被回滚（`True`）或应用（`False`）。
`apps`
  `Apps` 的实例，包含迁移运行前的项目状态。它应该代替全局 `apps` 注册表来检索你要执行操作的模型。

### `post_migrate`

`django.db.models.signals.``post_migrate`

在 `migrate` （即使没有运行迁移）和 `flush` 命令结束时发出。对于缺乏 `models` 模块的应用程序，它不会被发出。

该信号的处理者不能进行数据库模式的改变，因为如果在 `migrate` 命令期间运行 `flush` 命令，可能会导致 `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` 会被重新创建，用于使用修改过的 `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()` 装饰器／上下文管理器改变配置值时，会发出这个信号。

它实际上被发送了两次：当应用新的值时（"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`

当数据库包装器与数据库进行初始连接时发送。 如果你想向 SQL 后端发送任何连接后的命令，这一点特别有用。

用此信号发送的参数：

`sender`
  数据库封装类 —— 即 `django.db.backends.postgresql.DatabaseWrapper` 或 `django.db.backends.mysql.DatabaseWrapper` 等。
`connection`
  打开的数据库连接。这在多数据库配置中可以用来区分不同数据库的连接信号。