https://docs.djangoproject.com/zh-hans/3.2/topics/signals/
https://docs.djangoproject.com/zh-hans/3.2/ref/signals/

https://docs.djangoproject.com/zh-hans/4.0/topics/signals/

信号:signal
信号调度器:signal dispatcher
发送器:
接收器:
接收器函数:

发送信号时会调用接收器。信号的所有接收器函数都按照注册时的顺序一个接一个调用。

:::info 我的代码该放在哪?
严格来说,信号处理和注册的代码可以放在任何你喜欢的地方,但是推荐避免放在应用程序的根目录models 模块内以尽量减少导入代码的副作用。

在实践中,信号处理程序通常定义在与之相关的应用程序的 signals 子模块中。信号接收器在你应用程序配置类的 ready() 方法中连接。如果你使用 receiver() 装饰器,在 ready() 中导入 signals 子模块。 :::

连接接收器函数和信号
方法一:

  1. from django.db import models
  2. from django.db.models.signals import post_save
  3. class Site(models.Model):
  4. """Site模型类"""
  5. pass
  6. def my_callback(sender, **kwargs):
  7. """信号接收器函数"""
  8. pass
  9. pre_save.connect(my_callback, sender=Site)

方法二:

  1. from django.db.models.signals import post_save
  2. from django.dispatch import receiver
  3. from django.db import models
  4. class Site(models.Model):
  5. """Site模型类"""
  6. pass
  7. @receiver(post_save)
  8. def my_callback(Site, **kwargs):
  9. """信号接收器函数""""
  10. pass
  1. from django.db.models.signals import post_save
  2. from django.dispatch import receiver

好处:降低耦合度

models.py

  1. from django.db import models
  2. from django.db.models.signals import post_save
  3. from django.dispatch import receiver
  4. class Node(models.Model):
  5. """节点 模型类"""
  6. ENV_TYPE = (
  7. ('0', '生产环境'),
  8. ('1', '预生产环境'),
  9. ('2', '测试环境'),
  10. )
  11. node_name = models.CharField(max_length=36, verbose_name='节点名称')
  12. dev_env_type = models.CharField(max_length=1, choices=ENV_TYPE, verbose_name='开发环境的类型')
  13. def __str__(self):
  14. return f'{self.node_name}'
  15. class NodeExtension(models.Model):
  16. """节点的扩展信息 模型类"""
  17. node = models.OneToOneField(to='Node', verbose_name='关联的节点',
  18. on_delete=models.CASCADE, related_name='extension')
  19. remarks = models.TextField(verbose_name='描述性息')
  20. def __str__(self):
  21. return f'{self.node.node_name}'
  22. @receiver(post_save, sender=Node)
  23. def create_node_extension(sender, instance, created, **kwargs):
  24. """信号处理函数:当存储Node类型的对象时,自动创建并存储NodeExtension对象"""
  25. if created:
  26. NodeExtension.objects.create(node=instance)
  27. else:
  28. instance.extension.save()

image.png