标记为已删除,而不是在DeleteView中实际删除

时间:2015-02-15 18:57:28

标签: python django django-reversion

我正在使用Django中的DeleteView删除不同模型中的对象。

问题在于我不希望对象被完全删除,而只是隐藏。首先,我认为保持我的观点是有意义的,而是覆盖每个模型中的删除方法,如下所示

def delete(self, force=False):
    if force:
        return super(ModelName, self).delete()
    else:
        self.is_deleted = True
        self.save()

但后来我发现删除方法不会被批量删除调用,所以这种方法风险太大。

有人可以推荐一个好方法吗?我仍然希望保持DeleteView的正常行为,但它应该只是“停用”'对象而不是删除它们。

DeleteView如下:

def delete(self, request, *args, **kwargs):
    """
    Calls the delete() method on the fetched object and then
    redirects to the success URL.
    """
    self.object = self.get_object()
    success_url = self.get_success_url()
    self.object.delete()
    return HttpResponseRedirect(success_url)

如果我用

替换self.object.delete()就足够了
self.object.is_deleted = True
self.object.save()

当我将对象标记为已删除时,如何确保我的查询集不包含已删除的对象?我可以简单地在我的ListView中替换get_queryset()但是它们应该被排除在页面上的任何查询集之外,所以我想知道如果我自定义对象管理器我是否会得到更好的结果?

我一直在关注django-reversion。我可以简单地以正常方式删除所有对象,然后使用django-reversion,如果我想恢复它们吗?这个解决方案有什么缺点吗?

2 个答案:

答案 0 :(得分:1)

当我将对象标记为已删除时,如何确保我的查询集不包含已删除的对象?

正如评论所述,the Django-only solution is writing a customer Manager了解您的is_deleted字段。

  

我一直在关注django-reversion。我可以简单地以正常方式删除所有对象,然后使用django-reversion,如果我想恢复它们吗?

是的,只要你将你的删除包装在逆转中。这可以像using the reversion middleware一样简单地包装所有删除和保存:

MIDDLEWARE_CLASSES = (
    'reversion.middleware.RevisionMiddleware',
    # Other middleware goes here...
)
  

这个解决方案有什么缺点吗?

我发现没有,它得到了很好的支持,除了删除支持之外,还有版本跟踪。

答案 1 :(得分:1)

  

但后来我发现删除方法不会被批量调用   删除所以这种方法风险太大。

您可以为此编写自己的QuerySet并将其用作as_manager。相同的QuerySet可以处理隐藏已删除字段的显示。请记住留出一些方法来检索所有已删除的字段。