python - django 信号断开不工作

标签 python django django-signals

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

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。我做错了什么?

最佳答案

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

我相信有很多方法可以解决这个问题,但基本思路是确保您使用相同的引用函数调用 connectdisconnect。我已经包含了一个如何做到这一点的小样本。不要认为这是理所当然的,因为我刚刚做了一些小测试来验证它是否有效。

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]

关于python - django 信号断开不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35386423/

相关文章:

python - pandas.DataFrame 根据另一个 DataFrame 进行切片

python - 迭代或惰性水库采样

python - 用于复杂 numpy 数组的 Json 编码器和解码器

Django db_index 问题

python - 如何在查询集中使用 Django __time 查找

Django - 覆盖保存方法时检查旧值和新值之间的差异

python - post_save.disconnect 根本不起作用

django - 为 Django Heroku 应用程序、Amazon S3 设置 MEDIA_URL

Django 从 post_save 信号访问 ManyToMany 字段

python - Django CASCADE 和 post_delete 交互