Django signals allow applications to react automatically when certain actions occur on models, such as saving or deleting records. By connecting signals to models, developers can perform tasks like creating related objects, modifying data, sending notifications, or cleaning up files without tightly coupling logic to views.
pre_save, post_save, and post_deleteDjango provides built-in signals in django.db.models.signals. The @receiver decorator is used to connect a signal to a model and define the logic to run when the signal fires.
# Create a profile automatically after user creation
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import Profile
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
# Set default price before saving a book
from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import Book
@receiver(pre_save, sender=Book)
def set_default_price(sender, instance, **kwargs):
if not instance.price:
instance.price = 10.00
# Remove cover file after deleting 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()
Scenario: Simulate the post_save code example above. Create a User, and watch the system automatically create a Profile.
User Action → Model Event → Signal Trigger → Automatic Logic Execution
pre_save to normalize text fieldspost_delete