Some case we need to disable our signals temporary. No worries, because Django already provide the API for this.
Django has “connect” & “disconnect” method to enable or disable our signal.
Here is the example.
from django.db.models.signals import post_save # disable signal post_save.disconnect(your_signal_callable, sender=YourModel) # Your code implementation goes here. # re-enable signal post_save.connect(your_signal_callable, sender=YourModel)
But there’s more convenient way to temporary disable our signal. We can create context manager for make it reusable and more clean usage.
Here is the code,
class temporary_disconnect_signal(): def __init__(self, signal, receiver, sender, dispatch_uid=None): self.signal = signal self.receiver = receiver self.sender = sender self.dispatch_uid = dispatch_uid def __enter__(self): self.signal.disconnect( receiver=self.receiver, sender=self.sender, dispatch_uid=self.dispatch_uid, weak=False ) def __exit__(self, type, value, traceback): self.signal.connect( receiver=self.receiver, sender=self.sender, dispatch_uid=self.dispatch_uid, weak=False )
And here is how to use it.
with temporary_disconnect_signal(post_save, your_signal_callable, YourModel): # Your code implementation goes here.
Keep in mind, if your signal handler uses a dispatch_uid, you MUST use the dispatch_uid arg in context manager.