如何在Django模型中轻松将记录标记为已删除而不是实际删除它们?

时间:2009-04-13 14:34:31

标签: django django-models

我不想删除我的Django应用程序中的记录,而只是将它们标记为“已删除”,并将它们隐藏在我的活动查询中。我这样做的主要原因是为用户提供取消删除选项,以防他们意外删除记录(某些后端审计跟踪也可能需要这些记录。)

有很多外键关系,因此当我将记录标记为已删除时,我必须将“删除”标记“级联”到这些记录中。我应该使用哪些工具,现有项目或方法来执行此操作?

5 个答案:

答案 0 :(得分:11)

Django提供了开箱即用的确切机制。

您可以通过相关对象更改用于访问的管理器。如果新的自定义管理器在布尔字段上过滤对象,则标记为非活动的对象将不会显示在您的请求中。

请点击此处了解更多详情: http://docs.djangoproject.com/en/dev/topics/db/managers/#using-managers-for-related-object-access

答案 1 :(得分:4)

好问题,我一直想知道如何有效地做到这一点。

我不确定这是否能解决问题,但django-reversion似乎做了你想做的事,尽管你可能想检查一下它是如何实现这个目标的,因为有一些效率低下的方法可以做到这一点

另一个想法是在你的模型上有可怕的布尔标志,然后创建一个自动添加过滤器的自定义管理器,尽管这对于跨不同模型的搜索不起作用。另一个解决方案suggested here是拥有所有内容的重复模型,这看起来有点矫枉过正,但可能适合您。那里的评论也讨论了不同的选择。

我将补充一点,我认为这些解决方案中的任何一个都不值得麻烦;我通常只是把它吸掉并过滤我对布尔标志的搜索。如果你试图变得过于聪明,它可以避免许多问题。当然,这是一种痛苦而不是非常干燥。如果您尝试通过它搜索相关模型,合理的解决方案将是自定义管理器的混合,同时意识到其局限性。

答案 2 :(得分:3)

我认为使用布尔'is_active'标志很好 - 你不需要将标志级联到db级别的相关条目,你只需要继续引用父级的状态。这是contrib.auth的User模型所发生的事情,请记住 - 将用户标记为not isactive不会提示django通过相关模型并神奇地尝试停用记录,而只是继续检查用户对应的is_active属性。相关项目。

例如,如果每个用户都有许多书签,并且您不希望看到非活动用户的书签,请确保bookmark.user.is_active为true。在书签本身上不太可能需要is_active标志。

答案 3 :(得分:3)

这是几年前来自Greg Allard的快速博客教程,但是我使用Django 1.3实现了它并且很棒。我为我的对象添加了名为soft_delete,undelete和hard_delete的方法,它们分别设置self.deleted = True,self.deleted = False,并返回self.delete()。

A Django Model Manager for Soft Deleting Records and How to Customize the Django Admin

答案 4 :(得分:0)

有几个软件包提供此功能:https://www.djangopackages.com/grids/g/deletion/

我正在开发一个https://github.com/meteozond/django-permanent/ 它取代了默认的Manager和QuerySet删除方法,以引入逻辑删除。 它完全影响了默认的Django删除方法,只有一个例外 - 标记模型,它们继承自PermanentModel而不是删除,即使它们是由关系引起的删除。