How Django Signals Work

April 12, 2021, 6:32 a.m.

We are going to look at how Django signals work in this tutorial. Signals allow certain senders to notify a set of receivers that some action has taken place.


We will focus on the post_save signal in this tutorial, you can checkout a list of all signals here list of all signals


EXAMPLE


Assume you have a simple app to record book name and pages, a model for that app might look as shown below




class Book(models.Model):
    name = models.CharField(max_length=50)
    pages = models.CharField(max_length=50)

    def __str__(self):
        return self.name


Now assume you want to do something once a new book entry has been added to the database, how do you do that ? this is where signals come in.


HOW TO USE SIGNALS


Create a new file named signals.py in our app on the same level as models.py file.


mysite/signals.py



from django.db.models.signals import post_save
from django.dispatch import receiver

from mysite.models import Book


@receiver(post_save, sender=Book)
def Notify_if_book_is_saved(sender, **kwargs):
    if kwargs['created']:
        print("New book saved.")



The Notify_if_book_is_saved is our receiver function which will only be called when an instance of Book is saved, It simply prints " New book saved. " once a new book is saved.


Notice that our function takes a sender argument and keyword arguments (**kwargs); all signal handlers must take these arguments.


if keyword arguments (**kwargs) is new to you checkout my tutorial on that what are python args and kwargs


We can check whether an instance of Book was saved using if kwargs['created']:


created is a boolean sent to the receiver function as a keyword argument by post_save signal, checkout other arguments that are sent by post_save signal here Arguments sent with post_save signal


Modify your app.py as follows


mysite/app.py


from django.apps import AppConfig

class MysiteConfig(AppConfig):
    name = 'mysite'
    verbose_name = "Mysite"

    def ready(self):
        import mysite.signals
        pass


The next step will depend of the version of Django you are using.


if you are using Django 1.8+ , the documentation says that

New applications should avoid default_app_config. Instead they should require the dotted path to the appropriate AppConfig subclass to be configured explicitly in INSTALLED_APPS.

Example:


INSTALLED_APPS = [
   'mysite.apps.MysiteConfig',
]


For older versions of Django set the default_app_config variable as shown below inside __init__ .py file on same level as models.py .


mysite/__init__ .py


default_app_config = 'mysite.apps.MysiteConfig'


GET SOURCE CODE


https://github.com/felix13/django-signals


RESOURCES


Signals


header photo by Alex Knight on unsplash


Keep Learning