Using Django's built in signals and writing custom signals.

Reading Time : ~ .

Django has a beautiful feature of signals which will record all the actions performed on the particular model. In the current blog post, we’ll learn how to use Django's built-in signals and how to  create custom signal

Using Django’s built in Signals:
Django has a lot of built-in signals like pre_save, post_save, pre_delete and post_delete and etc., For more information about Django's built-in signals visit https://docs.djangoproject.com/en/1.9/ref/signals/. Now we’ll learn how to use Django's pre_delete signal with a simple example. In the way we use pre_delete in the present blog post we can use other signals also in the same way. We have two models called Author and Book their models are defined in models.py as below.

# In models.py
from django.db import models

class Author(models.Model):
    full_name = models.CharField(max_length=100)
    short_name = models.CharField(max_length=50)

class Book(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100)
    content = model.TextField()
    status = models.CharField(max_length=10, default=”Drafted”)
    author_id = model.PositiveIntegerField(null=True)

In the above two models we are not having an author as foreignKey to Book model, so by default when the Author gets deleted it won’t delete all the Books written by the author. This is the case where signals come to picture, we can achieve this by using pre_delete or post_delete signals. For this, we’ll write a receiver function which will be called on pre_delete of the author object. Write the following code in your models.py

def remove_books(sender, instance, **kwargs):
    author_id = instance.id
    Book.objects.filter(author_id=author_id).delete()

pre_delete.connect(remove_books, sender=Article)

In the above snippet sender is the model name on which the pre_delete signal is called, in the current example it is Author model. Remove_books is the receiver function which will be called on delete of the Author object. It takes sender, instance(the Author instance which is called for delete) and any other keyword arguments.

Writing Custom Signals:
Now in this section, we’ll learn, how to create custom signals using the same above example. Suppose if the author has to get an email when the Book status is changed to “Published”. For this, we have to create a file called signals.py to create a custom signal. By default all the signals are django.dispatch.Signal instances.

# In signals.py
import django.dispatch
book_publised = django.dispatch.Signal(providing_args=["book", “author”])

Create receivers.py which contains the receiver function which will be called when the signal is dispatched.

# In receivers.py
from django.dispatch import receiver
from .signals import *

@receiver(book_publised)
def send_mail_on_publish(sender, **kwargs):
    # contains the logic to send the email to author.

In the above snippet receiver is decorator which tells the book_published signal that send_mail_on_publish is the receiver function which will be called when the book_publisehd signal is dispatched.

We can dispatch signal anywhere as following.

book_published.send(sender=Book, book=<Book Instance>, user=<Author Instance>)
Note: The most important to be remembered is when we just call book_published.send(*****) it won’t hit the receiver function. To make the signal hit the receiver function is we have to import receiver in your app’s __init__.py. 

# In __init__.py

import receivers

But from Django 1.9+ if we import receivers in __init__.py, it will cause runtime error of Apps not ready. To avoid this issue we have to import this inside the ready function of your apps.py

# In apps.py

from django.apps import AppConfig
class LoadReceivers(AppConfig):
    name = testapp

    def ready(self):
        from . import receivers
    By Posted On
SENIOR DEVELOPER at MICROPYRAMID

Need any Help in your Project?Let's Talk

Latest Comments
Related Articles
Custom Decorators To Check User Roles And Permissions In Django Ramya Ambati

A decorator is a function that takes another function and returns a newer,prettier version of that function.

To know more about decorators in python see ...

Continue Reading...
Set Up Travis CI For Django project Ravi Kumar Gadila

Travis CI is a continuous integration service used to build and test applications hosted at GitHub. Here are simple steps to add CI to you ...

Continue Reading...
Querying with Django Q objects Dinesh Deshmukh

Querying with Django Q objects: Q object encapsulates a SQL expression in a Python object that can be used in database-related operations. Using Q objects ...

Continue Reading...

Subscribe To our news letter

Subscribe to our news letter to receive latest blog posts into your inbox. Please fill your email address in the below form.
*We don't provide your email contact details to any third parties