I need make a save with a model but i need disconnect some receivers of the signals before save it.
I mean,
I have a model:
class MyModel(models.Model):
...
def pre_save_model(sender, instance, **kwargs):
...
pre_save.connect(pre_save_model, sender=MyModel)
and in another place in the code i need something like:
a = MyModel()
...
disconnect_signals_for_model(a)
a.save()
...
reconnect_signals_for_model(a)
Because i need in this case, save the model without execute the function pre_save_model.
For a clean and reusable solution, you can use a context manager:
class temp_disconnect_signal():
""" Temporarily disconnect a model from a 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
)
Now, you can do something like the following:
from django.db.models import signals
from your_app.signals import some_receiver_func
from your_app.models import SomeModel
...
kwargs = {
'signal': signals.post_save,
'receiver': some_receiver_func,
'sender': SomeModel,
'dispatch_uid': "optional_uid"
}
with temp_disconnect_signal(**kwargs):
SomeModel.objects.create(
name='Woohoo',
slug='look_mom_no_signals',
)
Note: If your signal handler uses a dispatch_uid
, you MUST use the dispatch_uid
arg.