断开模型信号并在Django中重新连接 [英] Disconnect signals for models and reconnect in django

查看:86
本文介绍了断开模型信号并在Django中重新连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要保存一个模型,但是在保存之前,我需要断开信号接收器的连接。

I need make a save with a model but i need disconnect some receivers of the signals before save it.

我的意思是

我有一个模型:

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)

因为在这种情况下,请保存模型而不执行pre_save_model函数。

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',
    )

注意:如果信号处理程序使用 dispatch_uid ,则必须使用 dispatch_uid arg。

Note: If your signal handler uses a dispatch_uid, you MUST use the dispatch_uid arg.

这篇关于断开模型信号并在Django中重新连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆