Django Signals allows decoupled (independent) applications get notified when certain events occur elsewhere in the framework with the help of 'signal dispatcher'. The 'signal dispatcher' is Django's mechanism used to send and receive messages between different parts of an application which are instances of Signal, via the connect method.
The Django core also defines a ModelSignal, which is a subclass of Signal that allows the sender to be lazily specified as a string of the
Django Signals are Used:
Some of the most useful models’ signals are the following:
delete()is called) .
ManyToManyFieldon a model is changed.
There are two key concepts: the Sender and the Receiver:
Sender :- must either be a Python object, or None to receive events from any sender.
Receiver :- must be a function or an instance method which is to receive signals.
Listening to signals:
To receive a signal, register a receiver function using the
Signal.connect() method. The receiver function is called when the signal is sent.
connect(receiver, sender=None, weak=True, dispatch_uid=None)
weak=Falsewhen you call the signal’s
Let’s see how this works by registering a signal that gets called after each HTTP request is finished. We’ll be connecting to the
First, define a receiver function. A receiver can be any Python function or method:
def my_callback(sender, **kwargs): print("Request finished!")
Notice that the function takes a
sender argument, along with wildcard keyword arguments (
**kwargs); all signal handlers must take these arguments.
**kwargs argument, all signals send keyword arguments, and may change those keyword arguments at any time. In the case of
request_finished, it’s documented as sending no arguments, which means we might be tempted to write our signal handling as
This would be wrong – in fact, Django will throw an error if you do so. That’s because at any point arguments could get added to the signal and your receiver must be able to handle those new arguments.
There are two ways you can connect a receiver to a signal. You can take the manual connect route:
from django.core.signals import request_finished request_finished.connect(my_callback)
Alternatively, you can use a
Here’s how you connect with the decorator:
from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished) def my_callback(sender, **kwargs): print("Request finished!")
my_callback function will be called each time a request finishes.
Some signals get sent many times, but you’ll only be interested in receiving a certain subset of those signals. For example, consider the
django.db.models.signals.pre_save signal sent before a model gets saved. Most of the time, you don’t need to know when any model gets saved – just when one specific model is saved.
In these cases, you can register to receive signals sent only by particular senders. In the case of
django.db.models.signals.pre_save, the sender will be the model class being saved, so you can indicate that you only want signals sent by some model:
from django.db.models.signals import pre_save from django.dispatch import receiver from myapp.models import MyModel @receiver(pre_save, sender=MyModel) def my_handler(sender, **kwargs): ...
my_handler function will only be called when an instance of
MyModel is saved.
Different signals use different objects as their senders.
In some circumstances, the code connecting receivers to signals may run multiple times. This can cause your receiver function to be registered more than once, and thus called multiple times for a single signal event.
If this behavior is problematic (such as when using signals to send an email whenever a model is saved), pass a unique identifier as the
dispatch_uid argument to identify your receiver function. This identifier will usually be a string, although any hashable object will suffice. The end result is that your receiver function will only be bound to the signal once for each unique
from django.core.signals import request_finished request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")
We take the vision which comes from dreams and apply the magic of science and mathematics, adding the heritage of our profession and our knowledge to create a design.