Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Question 3 of 10 · Django Signals & Decorators
Interview question

What are best practices for using Django Signals? What are common pitfalls? Django Signals use करने की best practices क्या हैं? Common pitfalls क्या हैं?

Answer

Signals are powerful but can cause confusion and performance issues if misused. Follow best practices to avoid circular imports, performance problems, and debugging difficulties.

Best PracticeWhy
Define signals in signals.pyOrganized, avoid circular imports
Import in apps.py ready()Executed once at startup
Keep signal handlers lightweightThey block request processing
Use @receiver decoratorCleaner, more readable code
Avoid heavy queriesEach save triggers query
Use dispatch_uidPrevent duplicate signal connections
// ✅ CORRECT - signals.py with apps.py
// myapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Book

@receiver(post_save, sender=Book)
def update_cache(sender, instance, created, **kwargs):
    # Keep this lightweight
    cache.set(f"book_{instance.id}", instance)

// myapp/apps.py
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = "myapp"
    
    def ready(self):
        import myapp.signals  # Import signals

// ❌ WRONG - Signal in models.py (circular import risk)
// models.py - DON't do this!
from django.db.models.signals import post_save

@receiver(post_save, sender=Book)
def update_cache(sender, instance, **kwargs):
    pass  # Causes circular import issues

// Using dispatch_uid
@receiver(post_save, sender=Book, dispatch_uid="update_book_cache")
def update_cache(sender, instance, **kwargs):
    # dispatch_uid prevents duplicate connections
    pass

// ✅ Best: Async heavy operations
from celery import shared_task

@receiver(post_save, sender=Book)
def trigger_email(sender, instance, created, **kwargs):
    if created:
        send_email_async.delay(instance.id)

@shared_task
def send_email_async(book_id):
    book = Book.objects.get(id=book_id)
    send_notification_email(book)

// ❌ AVOID: Heavy queries in signals
@receiver(post_save, sender=Book)
def bad_handler(sender, instance, **kwargs):
    # Bad: This will be called for EVERY save
    all_books = Book.objects.all()  # Heavy query
    for book in all_books:
        book.update_something()

// ✅ CORRECT: Use select_related to optimize
@receiver(post_save, sender=Book)
def good_handler(sender, instance, **kwargs):
    # Only update related object
    instance.category.update_book_count()

// ✅ CORRECT: Disconnect signals in tests
from django.db.models.signals import post_save
from django.test import TestCase

class BookTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        post_save.disconnect(update_cache, sender=Book)
    
    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        post_save.connect(update_cache, sender=Book)

Signals powerful हैं लेकिन अगर गलत तरीके से use करें तो समस्याएं हो सकती हैं।

Best Practiceक्यों
signals.py में define करोOrganized, imports safe
apps.py में import करोCircular imports avoid
Lightweight handlersRequest block नहीं हो
Async भारी operationsPerformance improve
// signals.py में define करो
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Book, dispatch_uid="update_cache")
def update_cache(sender, instance, **kwargs):
    cache.set(f"book_{instance.id}", instance)

// apps.py में import करो
class MyAppConfig(AppConfig):
    def ready(self):
        import myapp.signals

Was this answer clear?