django signal disconnect not working

匆匆过客 提交于 2021-02-07 04:14:26

问题


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")

I can successfully connect the signals :

signal_processor = SearchSignalProcessor()             
signal_processor.setup(SomeModel)

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


回答1:


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.

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]


来源:https://stackoverflow.com/questions/35386423/django-signal-disconnect-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!