如何使用pre_delete信号普遍防止删除?

问题描述 投票:0回答:1

我在所有型号上都有一个公共字段is_active = models.BooleanField()

我想为删除功能创建一个通用替代,以便从数据库is_active = False而不是从数据库中删除记录。

我知道执行此操作的最佳方法是pre_delete信号,而不是将delete()本身覆盖为delete() is not called in bulk operations

我已经尝试了以下实现:

@receiver(pre_delete)
def delete_obj(sender, instance, **kwargs):
    """Override delete() to set object to inactive."""

    return instance.is_active == False

但是,这仍然会导致从数据库中删除对象。我认为这是因为delete()pre_delete之后仍被调用。我该如何纠正?

来自文档:

[请注意,当使用QuerySet批量删除对象或级联删除操作时,不必调用对象的delete()方法。为了确保执行自定义的删除逻辑,您可以使用pre_delete和/或post_delete信号。

django django-signals
1个回答
0
投票

您想替换原始方法的逻辑(在这种情况下,执行更新而不是删除)不是扩展

Signalsextend main方法logic,而不是替换它。

pre_信号中-在操作之前运行一些其他逻辑(甚至可以修改对象)。在post_信号中-在主要动作之后运行一些附加逻辑。但是主要动作仍在运行-应该-在代码中已正确调用-不应替换信号。

类似于模型上的扩展方法:您将在调用super().method()之前或之后添加一些逻辑-这就是信号的工作方式。

[用另一种逻辑替换方法逻辑-重写方法super()时,很可能不会调用,因此不执行原始操作。


因此,要用自定义逻辑替换delete(),您可以覆盖两个模型的delete()方法,并使用覆盖了delete()方法的模型使用自定义QuerySet,因此在模型实例或QuerySet上调用delete()时,它将执行更新代替。


Link to surce code where QuerySet delete is performed

  • [pre_delete信号已发送
  • 执行[delete_batch
  • [post_delete信号已发送
© www.soinside.com 2019 - 2024. All rights reserved.