python / expert
Snippet
Django Signals with WeakRef Callbacks and Custom Senders
Django signals provide a powerful pub/sub mechanism for decoupled communication between models. This snippet demonstrates advanced signal patterns including weak reference callbacks to prevent memory leaks, custom sender filtering for granular event handling, and a registry pattern for managing multiple signal connections. The CacheInvalidator class shows how to create reusable signal handlers that clean up related caches when models are modified.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from django.db.models.signals import post_save, pre_deletefrom django.dispatch import receiverimport weakrefclass CacheInvalidator:def __init__(self, cache):self.cache = cachedef __call__(self, sender, **kwargs):instance = kwargs.get('instance')if instance:self.cache.delete(f'object:{instance.pk}')class SignalRegistry:def __init__(self):self._callbacks = []def register(self, callback, sender):weak_cb = weakref.ref(callback)self._callbacks.append((weak_cb, sender))return weak_cbdef disconnect_all(self):for weak_cb, sender in self._callbacks:if weak_cb() is not None:post_save.disconnect(weak_cb(), sender=sender)pre_delete.disconnect(weak_cb(), sender=sender)self._callbacks.clear()cache_invalidator = CacheInvalidator(cache)@receiver(post_save, sender=Product)def on_product_save(sender, instance, **kwargs):cache_invalidator(sender=sender, instance=instance)
django
Breakdown
1
from django.db.models.signals import post_save, pre_delete
Imports Django's built-in signals for model lifecycle events
2
import weakref
Python's weakref module enables garbage collection by storing weak references instead of strong ones
3
class CacheInvalidator:
Custom callable class that implements cache invalidation logic
4
def __call__(self, sender, **kwargs):
Makes the instance callable so it can act as a signal receiver
5
weak_cb = weakref.ref(callback)
Converts strong reference to weak reference to prevent circular reference memory leaks
6
@receiver(post_save, sender=Product)
Decorator that registers the signal handler only for Product model saves