我在所有模型上都有一个公共字段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信号。
答案 0 :(得分:0)
您要替换原始方法的逻辑(在这种情况下,执行更新而不是删除)不对其进行扩展。< / p>
信号应扩展 主要方法逻辑,而不是替换。
在pre_
信号中-在操作之前运行一些其他逻辑(甚至可以修改对象)。在post_
信号中-在主要动作之后运行一些附加逻辑。但是主要动作仍在运行-应该-在代码中已正确调用-不应替换信号。
就像模型上的扩展方法一样:您将在调用super().method()
之前或之后添加一些逻辑-这就是信号的工作方式。
如果用另一种逻辑替换方法逻辑-覆盖方法super()
时很可能不会被调用,因此不会执行任何原始操作。
因此,要用自定义逻辑替换delete()
,您可以覆盖两个模型的delete()
方法,并使用被覆盖的delete()
方法为模型使用自定义QuerySet,这样在调用delete()
时,模型实例或QuerySet-它将执行更新。
Link to surce code where QuerySet delete is performed:
pre_delete
信号已发送delete_batch
已执行post_delete
信号已发送