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

时间:2022-04-13 00:35:15

TL;DR:
I need a way to trigger a custom signal after the post_save signal, automatically, is there any way of doing it?

TL; DR:我需要一种方法在post_save信号之后自动触发自定义信号,有没有办法做到这一点?


I'm currently developing a library for django that requires a lot of comes and goes with the post_save signal in django and I was wondering if it's possible to trigger another signal after the post_save so I could implement my own and not intervene the post_save in case a project that uses the library needs to do it.

我正在开发一个django的库,它需要很多来自django中的post_save信号,我想知道是否有可能在post_save之后触发另一个信号所以我可以实现自己的而不是干预post_save以防万一使用库的项目需要这样做。

So far I know that signals are expected to receive a class as a sender argument, and if I trigger manually the signal from the post_save I would be doing nothing (I'd still be intervening it). Is there any workaround for this? Am I missing something in the docs?

到目前为止,我知道信号预计将接收一个类作为发送者参数,如果我手动触发post_save中的信号,我将无所事事(我仍然会干预它)。这有什么解决方法吗?我在文档中遗漏了什么吗?

1 个解决方案

#1


7  

Although this may be possible by calling a signal manually from inside another signal like this:

虽然这可以通过从另一个信号中手动调用信号来实现,如下所示:

post_save.send(MyModel, instance=a_mymodel_instance)

There are easier ways to do something like that:

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

Let us assume that you follow the file organization that I use in this answer: Django Create and Save Many instances of model when another object are created

让我们假设您遵循我在此答案中使用的文件组织:Django创建并保存创建另一个对象时的许多模型实例


Suggestion 1:

建议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对MyModel1做了一些事情,而另一个post_save信号在触发第一个信号的实例上进行一些处理之后对MyModel2做了一些事情。
  • post_save is always send at the end of a save() method.
  • post_save总是在save()方法的末尾发送。
  • 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.

    这样,mymodel2_signal信号将在从mymodel1_signal调用MyModel2.save()之后被触发。


Suggestion 2:

建议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
  • 让我们假设你想在MyModel1 get的保存之前在MyModel2上启动一个进程
  • Use a pre_save and a post_save signal:

    使用pre_save和post_save信号:

    @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...
    

Suggestion 3:

建议3:

Use a MyModel2 method directly inside a MyModel1 post_save signal.

直接在MyModel1 post_save信号中使用MyModel2方法。

#1


7  

Although this may be possible by calling a signal manually from inside another signal like this:

虽然这可以通过从另一个信号中手动调用信号来实现,如下所示:

post_save.send(MyModel, instance=a_mymodel_instance)

There are easier ways to do something like that:

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

Let us assume that you follow the file organization that I use in this answer: Django Create and Save Many instances of model when another object are created

让我们假设您遵循我在此答案中使用的文件组织:Django创建并保存创建另一个对象时的许多模型实例


Suggestion 1:

建议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对MyModel1做了一些事情,而另一个post_save信号在触发第一个信号的实例上进行一些处理之后对MyModel2做了一些事情。
  • post_save is always send at the end of a save() method.
  • post_save总是在save()方法的末尾发送。
  • 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.

    这样,mymodel2_signal信号将在从mymodel1_signal调用MyModel2.save()之后被触发。


Suggestion 2:

建议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
  • 让我们假设你想在MyModel1 get的保存之前在MyModel2上启动一个进程
  • Use a pre_save and a post_save signal:

    使用pre_save和post_save信号:

    @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...
    

Suggestion 3:

建议3:

Use a MyModel2 method directly inside a MyModel1 post_save signal.

直接在MyModel1 post_save信号中使用MyModel2方法。