Bird
Raised Fist0
Djangoframework~10 mins

Receiver decorator in Django - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Receiver decorator
Define signal handler function
Apply @receiver decorator with signal
Connect handler to signal
Signal sent somewhere in app
Django calls connected handler
Handler executes with signal data
Shows how a function is decorated to listen for a signal, then called automatically when that signal is sent.
Execution Sample
Django
from django.dispatch import receiver, Signal

my_signal = Signal()

@receiver(my_signal)
def my_handler(sender, **kwargs):
    print('Signal received')
Defines a signal and a handler function that prints a message when the signal is received.
Execution Table
StepActionEvaluationResult
1Define my_signal as a new Signalmy_signal createdSignal object ready
2Define my_handler functionFunction createdFunction exists but not connected
3Apply @receiver(my_signal) decoratorConnect my_handler to my_signalmy_handler registered as listener
4Send my_signalDjango finds connected handlersmy_handler called
5my_handler runsPrint 'Signal received'Message output to console
6No more handlersSignal processing endsExecution complete
💡 All connected handlers called; signal processing finished
Variable Tracker
VariableStartAfter Step 1After Step 3After Step 4Final
my_signalundefinedSignal objectSignal objectSignal objectSignal object
my_handlerundefinedFunction objectConnected functionConnected functionConnected function
Key Moments - 2 Insights
Why does the handler function run only after the signal is sent?
Because the @receiver decorator only connects the function to the signal; the function runs when Django sends the signal (see execution_table step 4 and 5).
Can the handler function be called without sending the signal?
No, the handler runs only when the signal is sent. Defining and connecting it does not execute it immediately (see execution_table steps 2 and 3).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what happens at step 3?
AThe handler function prints output
BThe handler function is connected to the signal
CThe signal is sent
DThe signal object is created
💡 Hint
Check the 'Action' and 'Result' columns at step 3 in the execution_table
At which step does the handler function actually run?
AStep 5
BStep 4
CStep 2
DStep 1
💡 Hint
Look for when the handler prints output in the execution_table
If the signal is never sent, what happens to the handler function?
AIt runs immediately after definition
BIt runs when the app starts
CIt never runs
DIt runs twice
💡 Hint
Refer to the variable_tracker and execution_table steps 4 and 5
Concept Snapshot
Receiver decorator in Django:
- Use @receiver(signal) above a function
- Connects function to listen for that signal
- Function runs only when signal is sent
- Handler receives sender and kwargs
- Useful for decoupled event handling
Full Transcript
The receiver decorator in Django is used to connect a function to a signal. First, you define a signal object. Then, you write a handler function that will respond to that signal. By applying the @receiver decorator with the signal as argument, Django registers the function as a listener. When the signal is sent somewhere in the app, Django automatically calls the connected handler function, passing the sender and any extra data. The handler then executes its code, such as printing a message. This allows different parts of the app to communicate without tight coupling. The handler only runs when the signal is sent, not before.

Practice

(1/5)
1. What is the main purpose of the @receiver decorator in Django?
easy
A. To register a template filter
B. To create a new database model
C. To connect a function to a signal so it runs automatically when the signal is sent
D. To define a URL route in Django

Solution

  1. Step 1: Understand what signals do in Django

    Signals notify parts of your app when something happens, like saving a model.
  2. Step 2: Role of the @receiver decorator

    The decorator links a function to a signal so it runs automatically when the signal is sent.
  3. Final Answer:

    To connect a function to a signal so it runs automatically when the signal is sent -> Option C
  4. Quick Check:

    Receiver decorator connects functions to signals = D [OK]
Hint: Receiver links functions to signals for automatic execution [OK]
Common Mistakes:
  • Confusing receiver with model or URL definitions
  • Thinking receiver creates models or templates
  • Mixing up signals with URL routing
2. Which of the following is the correct syntax to use the @receiver decorator for the post_save signal of a model named Book?
easy
A. @receiver(post_save, sender=Book) def my_handler(sender, instance, **kwargs): pass
B. @receiver(post_save(Book)) def my_handler(sender, instance, **kwargs): pass
C. @receiver(sender=Book, post_save) def my_handler(sender, instance, **kwargs): pass
D. @receiver(post_save) def my_handler(Book, instance, **kwargs): pass

Solution

  1. Step 1: Check the correct decorator syntax

    The @receiver decorator takes the signal as first argument and sender=ModelName as keyword argument.
  2. Step 2: Match the correct function signature

    The handler function must accept sender, instance, and **kwargs.
  3. Final Answer:

    @receiver(post_save, sender=Book) def my_handler(sender, instance, **kwargs): pass -> Option A
  4. Quick Check:

    Correct decorator syntax = C [OK]
Hint: Use @receiver(signal, sender=Model) syntax [OK]
Common Mistakes:
  • Passing sender as positional argument
  • Incorrect function parameters
  • Missing sender keyword argument
3. Given this code snippet, what will be printed when a 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, **kwargs):
    print(f"Book saved: {instance.title}")

book = Book(title='Django Basics')
book.save()
medium
A. Book saved: None
B. Error: receiver not connected
C. No output printed
D. Book saved: Django Basics

Solution

  1. Step 1: Understand the signal connection

    The @receiver decorator connects notify to post_save for Book.
  2. Step 2: What happens on book.save()?

    Saving the book triggers post_save, calling notify, which prints the book's title.
  3. Final Answer:

    Book saved: Django Basics -> Option D
  4. Quick Check:

    post_save triggers print with instance title = B [OK]
Hint: post_save calls receiver printing instance data [OK]
Common Mistakes:
  • Assuming no output without explicit call
  • Confusing instance attribute access
  • Thinking receiver needs manual call
4. Identify the error in this signal receiver code:
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Author)
def handle_save(instance, **kwargs):
    print(f"Author saved: {instance.name}")
medium
A. Incorrect decorator usage, should not use sender
B. Missing sender parameter in function definition
C. Function name must be post_save_handler
D. No error, code is correct

Solution

  1. Step 1: Check function parameters for signal handlers

    Signal handlers must accept sender, instance, and **kwargs.
  2. Step 2: Identify missing parameter

    The function handle_save lacks the sender parameter, causing an error.
  3. Final Answer:

    Missing sender parameter in function definition -> Option B
  4. Quick Check:

    Signal handler must have sender parameter = A [OK]
Hint: Signal handlers need sender, instance, **kwargs parameters [OK]
Common Mistakes:
  • Omitting sender parameter
  • Wrong function signature order
  • Assuming function name matters
5. You want to run a function only when a User model instance is created (not updated). How do you use the @receiver decorator with post_save to achieve this?
hard
A. @receiver(post_save, sender=User) def user_created(sender, instance, created, **kwargs): if created: print('New user created')
B. @receiver(post_save, sender=User) def user_created(sender, instance, **kwargs): print('New user created')
C. @receiver(post_save, sender=User) def user_created(sender, instance, created=False, **kwargs): if created == False: print('New user created')
D. @receiver(post_save, sender=User) def user_created(sender, instance, **kwargs): if not created: print('New user created')

Solution

  1. Step 1: Understand the created flag in post_save

    The post_save signal passes a created boolean indicating if the instance was newly created.
  2. Step 2: Use created to run code only on creation

    Check if created: inside the receiver function to run code only when a new instance is created.
  3. Final Answer:

    @receiver(post_save, sender=User) def user_created(sender, instance, created, **kwargs): if created: print('New user created') -> Option A
  4. Quick Check:

    Use created flag in post_save receiver = A [OK]
Hint: Check 'created' flag in post_save receiver to detect new instances [OK]
Common Mistakes:
  • Ignoring the created parameter
  • Checking created incorrectly
  • Missing created parameter in function