Django has a signal dispatcher which notifies when certain event occurs in the framework. In simple this like a publisher and subscribers here sender is publisher and receiver is subscribers.

The connection between the senders and the receivers is done through “signal dispatchers”.

Django allow to create customer signals and has some build-ins too. Let’s look into them.

Where should be signal code live:

Django suggest it should be in inside the appconfig ready() method.

It’s always better if we create separate module called signals.py. We need to connect them on project start.

So best place is apps.py.

E.g.,

App name is sample and signals.py in root folder.

def ready(self):
    import sample.signals  # noqa
    

Sender Functions:

Django provides some useful built-in signals pre_save, post_save, pre_delete, post_delete, m2m_changed, request_started, request_finished.

when processing a request. request_started,  request_finished are sent. connection_created used to send every database connection. *_save , *_delete are send during the database operations.

We can also define our custom signals.

Receiver Functions:

A receiver must be a function or an instance method which is to receive signals.

Receiver we can define in two ways. Either using receiver decorator or signal_name.connect(receiver_func).

E.g.,

We use Django built-in signals pre_save.

from django.db.models.signals import pre_save
@receiver(pre_save)
def model_handler(sender,**kwargs):
    pass
pre_save.connect(receiver, sender='app_label.MyModel')

Alternative Connect:

pre_save.connect(receiver)

pre_save works for all models to specify sender or model

@receiver(pre_save, sender = mymodel)
def model_handler(sender,**kwargs):
    pass

Alternative Connect:

pre_save.connect(receiver, sender='app_label.MyModel')

Creating Customer Signals:

We can generate our own signals using Django Signal class.

E.g.,

import django.dispatch

custom_signal= django.dispatch.Signal()

We can use this signal anywhere(views, models) in our code and send the message.

customer_signal.send(sender='sender_name', *args)

Receiver with sender_name will automatically process this message.

@receiver(customer_signal)
def customer_signal_handler(sender,**kwargs):
    pass

Reference Links:

Official docs:

https://docs.djangoproject.com/en/3.1/topics/signals/

https://docs.djangoproject.com/en/3.1/ref/signals/

How to create signals with sample code?.

https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html