← Back to Chapters

Common Django Signals

? Common Django Signals

? Quick Overview

In Django, signals provide a powerful mechanism to trigger actions in response to changes in the database. Among the most common signals are pre_save, post_save, and post_delete. They allow you to execute custom logic before or after saving or deleting a model instance.

? Key Concepts

  • Signals notify parts of your app when events occur
  • Receivers listen and respond to signals
  • Used for automation, cleanup, and side effects

? What is a Signal in Django?

Signals are messages sent when certain actions occur in Django. When a model instance is saved or deleted, Django can emit signals that receiver functions can listen to and act upon.

⚙️ pre_save Signal

The pre_save signal is sent just before a model’s save() method is called. It is useful for modifying data before it is stored in the database.

? View Code Example
# Set default title before saving the book
from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import Book

@receiver(pre_save, sender=Book)
def update_book_title(sender, instance, **kwargs):
    if not instance.title:
        instance.title = "Untitled"

⚙️ post_save Signal

The post_save signal runs after a model instance has been saved. It is commonly used for sending notifications or creating related records.

? View Code Example
# Send notification after a new book is created
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Book, Notification

@receiver(post_save, sender=Book)
def send_book_created_notification(sender, instance, created, **kwargs):
    if created:
        Notification.objects.create(
            message=f"A book titled '{instance.title}' was added."
        )

⚙️ post_delete Signal

The post_delete signal is triggered after a model instance is removed from the database. It is useful for cleaning up related resources.

? View Code Example
# Remove associated cover image after deleting the book
from django.db.models.signals import post_delete
from django.dispatch import receiver
from .models import Book

@receiver(post_delete, sender=Book)
def delete_book_cover(sender, instance, **kwargs):
    if instance.cover:
        instance.cover.delete()

? Use Cases

  • Auto-fill missing fields
  • Send email or system notifications
  • Delete unused files from storage

? Interactive Simulator

Simulate saving a "Book" to see the order in which signals fire.

# Console logs will appear here...

✅ Tips & Best Practices

  • Keep signal logic lightweight
  • Use dispatch_uid to avoid duplicate signals
  • Register signals inside apps.py when possible

? Try It Yourself

  • Add a timestamp using pre_save
  • Create a profile object using post_save
  • Delete uploaded media files using post_delete