Django how to use the `` receiver`` decorator for a class instead of a function

Using Django Signals receiver decorator I have the following function.

 @receiver(post_save) def action_signal(sender, instance, created, **kwargs): pass 

Is it possible to use the receiver decorator in a class instead of a function? . For this, I would like to have a __init__ method, etc.

i.e. How can I make something like this work ...

 class ActionSignals def __init__(self): self.stuff @receiver(post_save) def action_signal(sender, instance, created, **kwargs): print(self.stuff) 
+5
source share
2 answers

Using the receiver decorator in a class method does not really make sense. When do you expect the object to be created and the __init__ method will be launched?

You can use the manual method to connect the signals instead of the receiver decorator.

First create an instance of the object:

 action_signal = ActionSignals() 

Then you can use the connect method to connect the signal:

 post_save.connect(action_signal.action_signal) 
+6
source

Adding a class-based signal handler

You can do it:

 class ActionSignals(object): def __init__(self, *args, **kwargs): # ... def __call__(self, *args, **kwargs): print(self.stuff) 

Then connect the signal handler:

 handler = ActionSignals() post_save.connect(handler) 

This uses the python "magic" __call__ , which allows you to use an instance of a class as a function.

Avoiding duplicates

Be careful when you add handlers to your code, as you can create duplicates. For example, if you want to put the second bit of code in the root module, it will add a handler each time the module is imported.

To avoid this, you can do the following :

 post_save.connect(handler, dispatch_uid="my_unique_identifier") 

As @Alasdair pointed out, you can add handlers to AppConfig.ready() (and this is the recommended place for this), although you can usually do this anywhere if you don't want to create unwanted duplicates.

See "Where should this code live?" in this document .

+3
source

Source: https://habr.com/ru/post/1233697/


All Articles