Custom signals let you send messages inside your Django app when something happens. This helps different parts of your app talk to each other without being tightly connected.
Custom signals in Django
Start learning this pattern below
Jump into concepts and practice - no test required
from django.dispatch import Signal # Define a custom signal my_signal = Signal() # Define a receiver function def my_receiver(sender, **kwargs): print(f"Signal received with args: {kwargs}") # Connect the receiver to the signal my_signal.connect(my_receiver) # Send the signal my_signal.send(sender=None, arg1='hello', arg2='world')
Signal: This is the message you send.
Receiver: This is the function that listens and reacts to the signal.
from django.dispatch import Signal # Create a signal without arguments simple_signal = Signal() # Receiver function def receiver(sender, **kwargs): print("Simple signal received") # Connect and send simple_signal.connect(receiver) simple_signal.send(sender=None)
from django.dispatch import Signal # Signal with arguments user_logged_in = Signal() def greet_user(sender, user, **kwargs): print(f"Welcome {user}!") user_logged_in.connect(greet_user) user_logged_in.send(sender=None, user='Alice')
This program creates a custom signal called order_completed. When the signal is sent with an order ID, the receiver prints a message to notify shipping.
from django.dispatch import Signal # Define a custom signal with one argument order_completed = Signal() # Receiver function that reacts to the signal def notify_shipping(sender, order_id, **kwargs): print(f"Order {order_id} completed. Notify shipping department.") # Connect the receiver to the signal order_completed.connect(notify_shipping) # Simulate sending the signal when an order is done order_completed.send(sender=None, order_id=12345)
Always connect your receiver functions before sending signals.
Use providing_args to document what data your signal sends, but Django does not enforce it.
Signals help keep your code clean by separating event handling from main logic.
Custom signals let parts of your Django app communicate without tight links.
Define signals, write receivers, connect them, then send signals when needed.
This helps organize code and add features like notifications or logging easily.
Practice
Solution
Step 1: Understand what custom signals do
Custom signals let different parts of a Django app send messages to each other without direct links.Step 2: Compare options to this purpose
Only To allow different parts of an app to communicate without being tightly connected describes this communication purpose; others describe unrelated features.Final Answer:
To allow different parts of an app to communicate without being tightly connected -> Option DQuick Check:
Custom signals = loose communication [OK]
- Thinking signals speed up queries
- Confusing signals with URL routing
- Believing signals create database tables
Solution
Step 1: Recall Django's Signal class syntax
The correct way is to create a Signal object with providing_args as a list of argument names.Step 2: Check each option's syntax
Only my_signal = Signal(providing_args=["instance", "created"]) uses Signal with providing_args correctly; others use wrong parameter names or lowercase Signal.Final Answer:
my_signal = Signal(providing_args=["instance", "created"]) -> Option BQuick Check:
Signal(providing_args=...) is correct syntax [OK]
- Using lowercase 'signal' instead of 'Signal'
- Using 'args' or 'provides' instead of 'providing_args'
- Passing arguments without a list
my_signal.send(sender=None, instance='obj1', created=True) is called?from django.dispatch import Signal, receiver
my_signal = Signal(providing_args=["instance", "created"])
@receiver(my_signal)
def my_receiver(sender, **kwargs):
print(f"Received: {kwargs['instance']}, Created: {kwargs['created']}")Solution
Step 1: Understand signal sending and receiver
The signal is sent with instance='obj1' and created=True. The receiver prints these values from kwargs.Step 2: Match printed output to sent values
The print statement uses kwargs['instance'] and kwargs['created'], so it prints 'obj1' and 'True'.Final Answer:
Received: obj1, Created: True -> Option AQuick Check:
Signal send values print correctly [OK]
- Confusing sender with instance
- Assuming created is False by default
- Thinking sender is required in print
from django.dispatch import Signal
my_signal = Signal(providing_args=["data"])
def receiver_func(sender, data):
print(f"Data: {data}")
my_signal.connect(receiver_func)Solution
Step 1: Check receiver function signature
Receivers must accept sender and **kwargs to handle all signal arguments flexibly.Step 2: Identify mismatch in receiver parameters
The receiver only accepts sender and data, missing **kwargs, which causes errors when extra arguments are sent.Final Answer:
The receiver function must accept **kwargs, not just named arguments -> Option AQuick Check:
Receiver needs **kwargs for signal args [OK]
- Forgetting **kwargs in receiver signature
- Importing Signal from wrong module
- Assuming connect requires sender argument
- Confusing list and tuple for providing_args
Solution
Step 1: Define signal with all expected arguments
Since you want to send both user and major_update, both must be listed in providing_args.Step 2: Send signal with matching arguments
When sending, include both user and major_update to match the signal definition and receiver expectations.Final Answer:
Define signal with providing_args=['user', 'major_update'] and send with user=user_obj, major_update=True -> Option CQuick Check:
Signal args must match send args [OK]
- Omitting arguments in providing_args
- Sending arguments not declared in providing_args
- Defining signal without providing_args but sending args
