| published by | Software Crafts |
|---|---|
| in blog | Software Crafts |
| original entry | Custom Signals in Django |
It's fairly well known in the community that signals are a bit of anti-pattern. They make code harder to reason about and generally there are other approaches that are clearer and easier to maintain. The time to use them is when you need to invert the control of some logic and are being particular about logical dependencies in your django project.
To me the other reason they are a bit of an anti-pattern is that most projects only use half of the functionality offered by only hooking into the default ones within Django itself, which while useful in certain scenarios are too generic to be properly useful. The power with signals comes when you define both the signal and reciever function. (Side note, most recievers are defined in signals.py in most projects, however I prefer to defined them in recievers.py).
Defining custom signals allow you to define business specific signals which get fired not in a generic way, but under specific circumstances and now with in the introduction of async signals could allow for a message-passing based Django project. You can do 1-2-1 messages, fanout based message passing within signals and deduplication. This is a project I want to try one day, while this would go against the norms, I would be interested to see it play out.
Finally, here is a quick reminder about how to create a custom signal:
import django.dispatch
task_completed = django.dispatch.Signal()
which then get's triggered as follows:
from .signals import task_completed
...
task_completed.send(sender='mysender', *args, **kwargs)
Then you hook in a reciever callback function as usual...and that's it!
Have you used custom signals? Let me know, I curious to know where they crop up.