Challenge 3: Invalidate the Cache on Save — Possible Solution ==================================================================== # catalog/signals.py from django.core.cache import cache from django.db.models.signals import post_save, post_delete from django.dispatch import receiver from .models import Book @receiver(post_save, sender=Book) def invalidate_book_stats_on_save(sender, instance, **kwargs): cache.delete("book_stats") @receiver(post_delete, sender=Book) def invalidate_book_stats_on_delete(sender, instance, **kwargs): cache.delete("book_stats") # catalog/apps.py — required wiring, per Chapter 4's gotcha from django.apps import AppConfig class CatalogConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "catalog" def ready(self): import catalog.signals # noqa: F401 WHY THIS WORKS -------------- - Two separate receivers cover both ways the cached stats could go stale: post_save fires for both NEW books being created and EXISTING books being updated (e.g. a price correction), while post_delete handles a book being removed entirely — both cases change what get_catalog_stats() from Challenge 1 would compute. - cache.delete("book_stats") removes the cached entry immediately — the NEXT call to cache.get_or_set("book_stats", get_catalog_stats, ...) after a save or delete will find nothing cached, so it recomputes the aggregate query fresh and caches the new, correct result. This is strictly better than waiting out the full 10-minute timeout from Challenge 1, during which the displayed stats would otherwise be visibly wrong. - This directly reuses the signal + apps.py wiring pattern from Chapter 4 — the same "sender doesn't need to know who's listening" decoupling applies here: nothing in the view or admin code that saves a Book needs to remember to also clear the cache; the signal handles it automatically, everywhere a Book is saved or deleted throughout the project (including the admin site from Course 1's final chapter). - As with any signal, the apps.py ready() import is what actually connects these receivers — without it, book saves would proceed silently with a now-stale cache never being cleared, with no error indicating why the stats look wrong.