Performance: pre_save and post_save signals
These signals affect server-side processing time before and after saving data, impacting backend response time and perceived page load speed.
Jump into concepts and practice - no test required
from django.db.models.signals import post_save from django.dispatch import receiver from threading import Thread @receiver(post_save, sender=MyModel) def async_post_save(sender, instance, **kwargs): def background_task(): expensive_calculation(instance) Thread(target=background_task).start()
from django.db.models.signals import pre_save from django.dispatch import receiver @receiver(pre_save, sender=MyModel) def heavy_pre_save(sender, instance, **kwargs): import time time.sleep(2) # Simulate slow processing instance.computed_field = expensive_calculation(instance)
| Pattern | Server Processing | Database Delay | Response Time Impact | Verdict |
|---|---|---|---|---|
| Heavy pre_save blocking logic | High CPU and wait | Delayed until logic finishes | Blocks response by seconds | [X] Bad |
| Lightweight pre_save logic | Minimal CPU | Minimal delay | Fast response | [OK] Good |
| Heavy post_save async logic | Runs after save, non-blocking | No delay to save | Fast response | [OK] Good |
| Heavy post_save blocking logic | High CPU after save | No delay to save | Blocks response | [!] OK but risky |
pre_save signal in Django?pre_savepre_save signal triggers just before saving a model instance to the database.post_save runs after saving, and deletion signals run on delete, so they don't match pre_save.pre_save = before save [OK]post_save signal to a model named Book?signal.connect(handler_function, sender=ModelClass).my_handler to post_save for Book.Author instance is saved?from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
@receiver(pre_save, sender=Author)
def before_save(sender, instance, **kwargs):
print('Before saving:', instance.name)
@receiver(post_save, sender=Author)
def after_save(sender, instance, created, **kwargs):
if created:
print('Created:', instance.name)
else:
print('Updated:', instance.name)
# Assume instance.name = 'Alice' and this is a new savepre_save runs before saving, so it prints 'Before saving: Alice' first.post_save runs after saving; since created=True, it prints 'Created: Alice'.Product). What is the likely problem?from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save)
def product_saved(sender, instance, **kwargs):
print('Product saved:', instance.name)@receiver(post_save) decorator needs a sender=ModelClass argument to connect specifically to Product.sender=Product, the handler listens to post_save for all models, causing it to run whenever any model is saved.slug field based on its title before saving, but only if the slug is empty. Which signal and approach is best?pre_save runs before saving, allowing modification of fields like slug before the database write.post_save runs after saving, so changing slug then requires another save. Overriding save() is possible but pre_save keeps logic separate and clean.