Django中提供了"信号调度",用于在框架执行操作时解耦,当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作

Django中内置的 signal 类型

model中的信号

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)前后,自动触发

数据库迁移时候的信号

pre_migrate  # 执行migrate命令前,自动触发
post_migrate  # 执行migrate命令后,自动触发

请求和响应的信号

request_started  # 请求到来前,自动触发
request_finished  # 请求结束后,自动触发
got_request_exception  # 请求异常后,自动触发

Database

connection_created  # 创建数据库连接时,自动触发

信号的使用

内置信号的触发者已经集成到Django中,所以其会自动调用,只需要连接接收器函数即可

定义接收器函数

def notify_handler(sender, **kwargs):
    print("notify_handler")

连接接收器函数

from django.core.signals import request_finished
from django.dispatch import receiver

request_finished.connect(notify_handler)  # 手动连接

@receiver(request_finished)  # 使用装饰器
def notify_handler(sender, **kwargs):
    print("notify_handler")

model信号的使用

有以下model

class User(models.Model)

    name = models.CharField(max_length=20)
    email = models.EmailField(null=True)

@receiver(post_save, sender=User)
def handler(sender, **kwargs):
    print("do somethings")

这样,每当User模型执行save()方法时,就会执行这个函数

此外,此信号还可以传入两个参数,instancecreated

  • instance即这个模型的一个实例
  • created表示是否是创建实例

我们可以修改上面的handler

@receiver(post_save, sender=User)
def handler(sender, instance, created, **kwargs):
    if created and instance.email:
        print("发送邮件")

在某些情况下,信号函数在监听到信号时,信号函数可能被多次执行,因此我们需要传入一个dispatch_uid的参数,这个参数的值通常是一个我们自己写的字符串,这样就能防止在某些特定情况下信号函数被多次调用

@receiver(post_save, sender=User, dispatch_uid="send_email_notify")
def handler(sender, instance, created, **kwargs):
    if created and instance.email:
        print("发送邮件")

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:https://www.ltfred.com/article/django-signals/