当前位置:  开发笔记 > 编程语言 > 正文

Django - 我怎么_not_发送信号?

如何解决《Django-我怎么_not_发送信号?》经验,为你挑选了3个好方法。

我为我的模型编写了一些智能通用计数器和管理器(以避免select count查询等).因此,我为post_save做了一些重要的逻辑.

我想在没有必要的时候阻止处理信号.我想完美的界面将是:

instance.save(dispatch_signal=False)

我怎么能做到这一点?


更新

有关我正在做什么的更多信息,如果有人感兴趣:

    通用计数器存储在单独的表中

    每次Django对对象列表进行分页时,它都会调用我的自定义管理器的overriden count()方法,该方法基本上检索适当对象类的静态计数器值.

    信号触发计数器更新的逻辑,这有点复杂,因为它检查相关模型的许多方面(即它必须基于嵌套的类别树生成可见性属性).我不能把这个逻辑放在Model.save()中,因为一个计数器依赖于许多不同的模型.我希望将这种逻辑整合在一起,而不是散布的碎片.

    我正在对我的一些模型进行反规范化,所以我在表格中重写(复制)某些值.

    出于测试目的,我运行我的小命令扩展 - Dilla,以填充随机数据.

    我注意到不需要的信号触发,因此我希望它们有条件地运行.

希望它足够清楚.请原谅我的语言错误.



1> Сыч..:

一个快速而肮脏的解决方案是:

from django.db.models.signals import post_save
from somewhere_in_my_app import my_post_save_handler

post_save.disconnect(my_post_save_handler)
instance.save()
post_save.connect(my_post_save_handler)

但是,我强烈建议将您的逻辑转移到save()模型的方法中.


当需要信号的并行发生的事情时,这是有问题的.

2> Izz ad-Din R..:

您可以断开并重新连接信号.尝试使用with:此实用程序类的语句:

class SignalBlocker(object):
    def __init__(self, signal, receiver, **kwargs):
        self.signal = signal
        self.receiver = receiver
        self.kwargs = kwargs

    def __enter__(self, *args, **kwargs):
        self.signal.disconnect(self.receiver)

    def __exit__(self, *args, **kwargs):
        self.signal.connect(self.receiver, **self.kwargs)

您现在可以使用:

with SignalBlocker(post_save, my_post_save_handler):
    instance.save()


信号在Django中是全球性的.使用`with`仍然无法帮助`post_save`全局断开连接,即使它是短时间的.我会说覆盖`save`方法仍然比在这种情况下使用信号更好.

3> 小智..:

我找到了简单易用的解决方案:

MyModel.objects.filter(pk=instance.id).update(**data)

这是由于(https://docs.djangoproject.com/en/1.5/ref/models/querysets/#update):

最后,意识到update()在SQL级别进行更新,因此不会在模型上调用任何save()方法,也不会发出pre_save或post_save信号(这是调用Model.save的结果) )).

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有