我在所有型号上都有一个公共字段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信号。
您想替换原始方法的逻辑(在这种情况下,执行更新而不是删除)不是到扩展。
Signals将extend 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
信号已发送