首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django移除大容量删除

Django移除大容量删除
EN

Stack Overflow用户
提问于 2013-12-29 17:36:08
回答 2查看 1.2K关注 0票数 4

这是一个非常简单的问题:有什么好的方法来禁用对整个Django项目中所有模型的大容量删除调用吗?

这样做的理由是在完全删除数据的前提下,几乎总是错误的选择,而意外的大容量删除可能是有害的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-29 20:52:42

就像第一篇文章中的注释一样,您必须为以下每个元素创建一个子类:

  1. 模型经理
  2. Queryset类
  3. BaseModel

经过一些搜索,这里有一个很好的例子。,都归功于博客作者Akshay。在查看代码之前,请注意:

然而,它不可避免地导致数据损坏。问题很简单:使用布尔值存储删除状态使您无法在数据库中强制执行唯一性约束。

代码语言:javascript
运行
复制
from django.db import models
from django.db.models.query import QuerySet


class SoftDeletionQuerySet(QuerySet):
    def delete(self):
        # Bulk delete bypasses individual objects' delete methods.
        return super(SoftDeletionQuerySet, self).update(alive=False)

    def hard_delete(self):
        return super(SoftDeletionQuerySet, self).delete()

    def alive(self):
        return self.filter(alive=True)

    def dead(self):
        return self.exclude(alive=True)


class SoftDeletionManager(models.Manager):
    def __init__(self, *args, **kwargs):
        self.alive_only = kwargs.pop('alive_only', True)
        super(SoftDeletionManager, self).__init__(*args, **kwargs)

    def get_queryset(self):
        if self.alive_only:
            return SoftDeletionQuerySet(self.model).filter(alive=True)
        return SoftDeletionQuerySet(self.model)

    def hard_delete(self):
        return self.get_queryset().hard_delete()


class SoftDeletionModel(models.Model):
    alive = models.BooleanField(default=True)

    objects = SoftDeletionManager()
    all_objects = SoftDeletionManager(alive_only=False)

    class Meta:
        abstract = True

    def delete(self):
        self.alive = False
        self.save()

    def hard_delete(self):
        super(SoftDeletionModel, self).delete()

基本上,它添加了一个alive字段来检查该行是否已被删除,并在调用delete()方法时对其进行更新。

当然,此方法仅适用于可以操作代码库的项目。

票数 3
EN

Stack Overflow用户

发布于 2015-08-27 18:17:13

有一些优秀的现成应用程序允许还原已删除的模型(如果您感兴趣的话),下面是我使用的应用程序:

如果您真的想禁止批量删除,我会劝阻您不要使用这种方法,因为它会:

  • 打破对应用行为的期望。如果我调用MyModel.objects.all().delete(),我希望之后表是空的。
  • 破坏现有的应用程序。

如果你想这样做,请遵照评论中的建议:

我猜想这将包括子类化QuerySet和根据您的喜好更改delete方法,对默认管理器进行子类化,并让它使用自定义查询集、子类模型--创建一个抽象模型并让它使用您的自定义管理器,然后让所有模型子类为您的自定义抽象模型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20828111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档