如何从其他信号发送Django信号

8

TL;DR:
我需要一种方法,在post_save信号触发后自动触发自定义信号,有什么办法可以实现吗?


我正在开发一个Django库,它需要大量使用post_save信号,我想知道是否有可能在post_save之后触发另一个信号,以便我能实现自己的信号并不干扰post_save,以防使用该库的项目也需要这样做。

目前我知道信号应该接收一个类作为发送方参数,如果我从post_save手动触发信号,就什么都没做(我仍旧会干扰它)。 有没有任何解决方法? 我在文档中漏掉了什么?


你为什么需要自定义信号?如果你需要在每次保存时执行某些操作,那么只需使用post_save信号即可。无论是否使用传递给信号处理程序的所有参数都没有关系。 - solarissmoke
嘿,@OscarCarballal,我想知道,你觉得我的回答有帮助吗? - John Moutafis
是的,抱歉,我完全忘记标记它了。谢谢 :) - CastleDweller
1个回答

6

虽然可以通过从另一个信号内手动调用信号来实现这一点,例如:

post_save.send(MyModel, instance=a_mymodel_instance)

有更简单的方法来完成这样的事情:

假设您遵循我在此答案中使用的文件组织方式:Django Create and Save Many instances of model when another object are created


建议1:

  • Let us assume that your first post_save does something to MyModel1 and another post_save signal does something to MyModel2 after some processing on the instance that triggered the first signal.
  • post_save is always send at the end of a save() method.
  • Organize your signals as follows:

    @receiver(post_save, sender=MyModel1)
    def mymodel1_signal (sender, instance, **kwargs):
        Do stuff on MyModel1 instance...
        Do also stuff on MyModel2 and then call MyModel2.save()
    
    
    @receiver(post_save, sender=MyModel2)
    def mymodel2_signal (sender, instance, **kwargs):
        Do stuff on MyModel2 instance...
    

    This way the mymodel2_signal signal will get triggered after the call to MyModel2.save() from mymodel1_signal.


建议2:


  • Use a mix of signals to achieve the correct "timing".
  • Let us assume that you want to start a process on MyModel2 before a MyModel1 get's saved
  • Use a pre_save and a post_save signal:

    @receiver(pre_save, sender=MyModel1)
    def mymodel1_signal (sender, instance, **kwargs):
        Do stuff on MyModel1 instance...
        Do also stuff on MyModel2 and then call MyModel2.save()
    
    
    @receiver(post_save, sender=MyModel2)
    def mymodel2_signal (sender, instance, **kwargs):
        Do stuff on MyModel2 instance...
    

建议 3:

MyModel1post_save 信号中直接使用 MyModel2 方法。


当需要操作多个实例时,我们可以使用Django Channel触发一个离线任务来处理它。 - Hayden
@Hayden,目前我没有使用django-channels的经验。所以你说的听起来很有趣 :) - John Moutafis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接