Skip to content

Instantly share code, notes, and snippets.

@bruce-shi
Forked from RobertKolner/disable_signals.py
Created September 18, 2016 02:44
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save bruce-shi/fd0e3f5e2360c64bc9ce2efb254744f7 to your computer and use it in GitHub Desktop.
Save bruce-shi/fd0e3f5e2360c64bc9ce2efb254744f7 to your computer and use it in GitHub Desktop.
Temporarily disable all signals in django.
from collections import defaultdict
from django.db.models.signals import *
class DisableSignals(object):
def __init__(self, disabled_signals=None):
self.stashed_signals = defaultdict(list)
self.disabled_signals = disabled_signals or [
pre_init, post_init,
pre_save, post_save,
pre_delete, post_delete,
pre_migrate, post_migrate,
]
def __enter__(self):
for signal in self.disabled_signals:
self.disconnect(signal)
def __exit__(self, exc_type, exc_val, exc_tb):
for signal in self.stashed_signals.keys():
self.reconnect(signal)
def disconnect(self, signal):
self.stashed_signals[signal] = signal.receivers
signal.receivers = []
def reconnect(self, signal):
signal.receivers = self.stashed_signals.get(signal, [])
del self.stashed_signals[signal]
# Example usage:
# with DisableSignals():
# user.save() # will not call any signals
@isaacphi
Copy link

isaacphi commented Dec 7, 2022

I recommend adding signal.sender_receivers_cache.clear() to the reconnect method to avoid hours of debugging 😢

@joseluratm
Copy link

I recommend adding signal.sender_receivers_cache.clear() to the reconnect method to avoid hours of debugging 😢

I love you man

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment