Signals let parts of a Django app talk to each other without being tightly connected. This makes the app easier to change and grow.
Why signals enable decoupled communication in Django
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Django
from django.db.models.signals import signal_name from django.dispatch import receiver @receiver(signal_name, sender=ModelName) def function_name(sender, instance, **kwargs): # code to run when signal is sent
@receiver connects your function to the signal.
sender limits the signal to a specific model or source.
Examples
Django
from django.db.models.signals import post_save from django.dispatch import receiver from myapp.models import Book @receiver(post_save, sender=Book) def book_saved(sender, instance, **kwargs): print(f"Book saved: {instance.title}")
Django
from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished) def request_done(sender, **kwargs): print("A request finished.")
Sample Program
This example shows a signal that prints a message when an Article is saved. The signal function is separate from the Article model, so they are loosely connected.
Django
from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class Article(models.Model): title = models.CharField(max_length=100) @receiver(post_save, sender=Article) def article_saved(sender, instance, **kwargs): print(f"Article '{instance.title}' was saved.") # Simulate saving an Article instance article = Article(title='Django Signals') article.save()
Important Notes
Signals help keep your code clean by separating event reactions from main logic.
Be careful not to overuse signals, as too many can make debugging harder.
Always connect signals in apps.py or signals.py and import them properly to ensure they work.
Summary
Signals let parts of Django apps communicate without tight links.
This makes apps easier to maintain and extend.
Use signals to react to events like saving or deleting data.
Practice
1. Why do Django signals help create decoupled communication between app components?
easy
Solution
Step 1: Understand what decoupled communication means
Decoupled communication means parts work independently without direct connections.Step 2: Analyze how signals work in Django
Signals let one part send a message and others listen and react without knowing each other.Final Answer:
Because signals allow components to send and receive messages without knowing each other directly -> Option CQuick Check:
Signals enable decoupling = Because signals allow components to send and receive messages without knowing each other directly [OK]
Hint: Signals let parts talk without tight links [OK]
Common Mistakes:
- Thinking signals create database tables
- Believing signals force tight coupling
- Confusing signals with models
2. Which of the following is the correct way to connect a signal handler to Django's
post_save signal?easy
Solution
Step 1: Recall Django signal connection syntax
The correct syntax issignal.connect(handler, sender=Model).Step 2: Match the options to this syntax
post_save.connect(my_handler, sender=MyModel) matches the correct syntax exactly.Final Answer:
post_save.connect(my_handler, sender=MyModel) -> Option AQuick Check:
Signal connect syntax = post_save.connect(my_handler, sender=MyModel) [OK]
Hint: Use signal.connect(handler, sender=Model) to connect [OK]
Common Mistakes:
- Using send() instead of connect()
- Reversing handler and signal in connect()
- Calling connect as a method on handler
3. Given this code snippet, what will be printed when a new
Book instance is saved?from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Book)
def notify(sender, instance, created, **kwargs):
if created:
print(f"New book added: {instance.title}")
book = Book(title='Django Basics')
book.save()medium
Solution
Step 1: Understand the signal and receiver setup
The@receiverdecorator connectsnotifytopost_saveforBook.Step 2: Analyze what happens on
Sincebook.save()createdis True for a new instance, the print statement runs with the book title.Final Answer:
New book added: Django Basics -> Option BQuick Check:
post_save with created=True prints title = New book added: Django Basics [OK]
Hint: post_save with created=True triggers print [OK]
Common Mistakes:
- Assuming no output without explicit call
- Confusing created flag meaning
- Forgetting @receiver decorator effect
4. Identify the error in this signal handler code that prevents it from working correctly:
from django.db.models.signals import pre_delete
def cleanup(sender, instance):
print(f"Cleaning up {instance}")
pre_delete.connect(cleanup)medium
Solution
Step 1: Check handler function signature
Django signal handlers must accept**kwargsto avoid errors.Step 2: Verify the handler parameters
The handler lacks**kwargs, so it will raise an error when called.Final Answer:
Missing**kwargsparameter in handler function -> Option DQuick Check:
Handler needs **kwargs = Missing**kwargsparameter in handler function [OK]
Hint: Always include **kwargs in signal handlers [OK]
Common Mistakes:
- Omitting **kwargs in handler parameters
- Thinking sender argument is always required in connect()
- Confusing pre_delete and post_delete signals
5. You want to send a custom signal when a user completes a profile update, but you want to keep your app decoupled from the profile update logic. Which approach best uses Django signals to achieve this?
hard
Solution
Step 1: Understand decoupling goal
Decoupling means the profile update code should not know about who reacts to the event.Step 2: Analyze options for decoupled communication
Sending a custom signal inside the update function and connecting receivers elsewhere keeps components independent.Final Answer:
Define a custom signal and send it inside the profile update function; connect receivers elsewhere to react -> Option AQuick Check:
Custom signal sending keeps decoupling = Define a custom signal and send it inside the profile update function; connect receivers elsewhere to react [OK]
Hint: Send custom signals; connect receivers separately [OK]
Common Mistakes:
- Calling receivers directly, causing tight coupling
- Using global variables instead of signals
- Importing receivers inside update logic
