How to send a django signal from another signal

TL; DR:
I need a way to trigger a custom signal after a post_save signal, automatically, is there a way to do this?


I am currently developing a library for django that requires a lot of things and comes with a post_save signal in django, and I was wondering if it is possible to fire another signal after post_save so I could implement my own and not interfere with post_save in case if a project that uses the library needs to do this.

Until now, I know that the signals are expected to receive the class as the sender argument, and if I manually call the signal from post_save, I will not do anything (I will interfere with it anyway). Is there a workaround for this? Am I missing something in the docs?

+8
python django django-signals
source share
1 answer

Although it may be possible by manually triggering a signal from another signal as follows:

 post_save.send(MyModel, instance=a_mymodel_instance) 

There are simpler ways to do something like this:

Suppose you follow the file organization that I use in this answer: Django Create and save many model instances when creating another object


Suggestion 1:

  • Suppose your first post_save doing something with MyModel1 and the other post_save signal post_save doing something MyModel2 after some processing of the instance that caused the first signal.
  • post_save always dispatched with the end of the 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... 

    Thus, the signal mymodel2_signal activated after calling MyModel2.save() from mymodel1_signal .


Suggestion 2:

  • Use a combination of signals to achieve the correct "time".
  • Suppose you want to start a process on MyModel2 before MyModel1 gets saved
  • Use pre_save and 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... 

Proposition 3:

Use the MyModel2 method directly inside the MyModel1 post_save signal.

+6
source share

All Articles