django信号断开不起作用 [英] django signal disconnect not working

查看:80
本文介绍了django信号断开不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个信号类,其中定义了信号接收器

I have a signal class where I define signal receivers

class SearchSignalProcessor(object):
    def post_save_connector(self, sender, instance, **kwargs):
        # do something

    def pre_delete_connector(self, sender, instance, **kwargs):
        # do something

    def setup(self, model):
        signals.post_save.connect(self.post_save_connector, sender=model, dispatch_uid="index_after_save")
        signals.pre_delete.connect(self.pre_delete_connector, sender=model, dispatch_uid="index_before_delete")

    def teardown(self, model):
        signals.pre_delete.disconnect(self.pre_delete_connector, sender=model, dispatch_uid="index_after_save")
        signals.post_save.disconnect(self.post_save_connector, sender=model,  dispatch_uid="index_before_delete")

我可以成功连接信号:

signal_processor = SearchSignalProcessor()             
signal_processor.setup(SomeModel)

disconnect 不起作用.我尝试使用和不使用 dispatch_uid ,每次它都返回False时.我在做什么错了?

but disconnect doesn't work. I tried with and without dispatch_uid, each time it just returns False. What am I doing wrong?

推荐答案

我认为注销失败的原因是由于您正在使用属于信号处理器实例的函数.因此,它们对于您的类的每个实例都是唯一的.我假设(尚未检查)Django的信号系统通过使用所述函数的哈希值来跟踪已注册的函数.因此,当您第二次实例化您的类以注销相同的功能时,它们将具有新的哈希,而django的信号系统无法找到它们.

I believe the reason the unregistering does not work is due to the fact that your are using functions belonging to an instance of your signal processor. Thus they are unique for each instance of your class. I am assuming (have not checked) that Django's signal system keeps track of registered functions by using hashes of said functions. So when you are instanciating your class a second time to unregister the same functions, they have a new hash and cannot be found by django's signal system.

我肯定有很多方法可以解决此问题,但是基本思想是确保您使用相同的引用函数调用 connect disconnect .我提供了一个有关如何做到的小样本.不要认为这是理所当然的,因为我刚刚进行了一些小测试以验证它是否有效.

I am sure there are many ways to solve this, but the basic idea is to make sure that you are calling connect and disconnect with the same referenced function. I have included a small sample of how one could do it. Don't take it for granted as I have just done some minor testing to verify that it works.

class SearchSignalProcessor(object):

    registry = {}

    @staticmethod
    def get_post_save_connector():
        def post_save_connector(sender, instance, **kwargs):
            #Do something
        return post_save_connector

    @staticmethod
    def get_pre_delete_connector():
        def pre_delete_connector(sender, instance, **kwargs):
            # Do something
        return pre_delete_connector

    def setup(self, model):
        if model in self.registry:
            self.teardown(model)

        self.registry[model] = {
            'pre_delete': self.get_pre_delete_connector(),
            'post_save': self.get_post_save_connector()
        }

        signals.post_save.connect(
            self.registry[model]['post_save'], 
            sender=model,
            dispatch_uid="index_after_save"
        )
        signals.pre_delete.connect(
            self.registry[model]['pre_delete'], 
            sender=model, 
            dispatch_uid="index_before_delete"
        )

   def teardown(self, model):
        if model in self.registry:
            signals.pre_delete.disconnect(self.registry[model]['post_save'])
            signals.post_save.disconnect(self.registry[model]['pre_delete'])
            del self.registry[model]

这篇关于django信号断开不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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