Django Signals (pre_save, post_save, etc.)
Signals let you execute code in response to events — when a model is saved, deleted, or when a user logs in. They decouple the sender from the receiver, allowing different parts of your app to react to events without tight coupling.
20 min•By Priygop Team•Updated 2026
Built-in Signals
- pre_save — Before model.save()
- post_save — After model.save() (created=True for new objects)
- pre_delete / post_delete — Before/after deletion
- m2m_changed — ManyToMany relationship changed
- request_started / request_finished — HTTP lifecycle
- user_logged_in / user_logged_out — Auth events
- Connect receivers with @receiver decorator
Signal Examples
Signal Examples
# blog/signals.py
# from django.db.models.signals import post_save, pre_delete
# from django.contrib.auth.signals import user_logged_in
# from django.dispatch import receiver
# from django.conf import settings
# from .models import Profile
# Auto-create profile when user is created
# @receiver(post_save, sender=settings.AUTH_USER_MODEL)
# def create_user_profile(sender, instance, created, **kwargs):
# if created:
# Profile.objects.create(user=instance)
# Log when posts are deleted
# @receiver(pre_delete, sender='blog.Post')
# def log_post_deletion(sender, instance, **kwargs):
# import logging
# logger = logging.getLogger(__name__)
# logger.warning(f"Post deleted: {instance.title} by {instance.author}")
# Track user logins
# @receiver(user_logged_in)
# def on_user_login(sender, request, user, **kwargs):
# user.last_login_ip = request.META.get('REMOTE_ADDR')
# user.save(update_fields=['last_login_ip'])
# blog/apps.py — Register signals
# class BlogConfig(AppConfig):
# default_auto_field = 'django.db.models.BigAutoField'
# name = 'blog'
#
# def ready(self):
# import blog.signals # noqa: F401Tip
Tip
Use post_save signal with created=True for new object creation actions like sending welcome emails or creating profiles.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Connecting signals in models.py. Use AppConfig.ready() in apps.py to import signals. This prevents import issues.
Practice Task
Note
(1) Create a post_save signal for UserProfile creation. (2) Register it in apps.py ready(). (3) Test profile auto-creation.
Quick Quiz
Key Takeaways
- Signals let you execute code in response to events — when a model is saved, deleted, or when a user logs in.
- pre_save — Before model.save()
- post_save — After model.save() (created=True for new objects)
- pre_delete / post_delete — Before/after deletion