Django删除批量删除

时间:2013-12-29 17:36:09

标签: python django django-queryset

这是一个非常简单的问题:在整个Django项目中,是否有任何好方法可以禁用所有模型上的批量删除(通过查询集)?

这样做的理由是,完全删除数据几乎总是一个糟糕的选择,而意外的批量删除可能是有害的。

2 个答案:

答案 0 :(得分:3)

就像您在第一篇文章中所说的那样,您必须为每个元素创建一个子类:

  1. 模特经理
  2. Queryset类
  3. BaseModel
  4. 经过一些搜索,a great example can be found here,博客作者Akshay Shah的所有学分。在查看代码之前,请注意:

      

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

    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()方法时更新它。
    当然,此方法仅适用于可以操作代码库的项目。

答案 1 :(得分:0)

有很好的现成应用程序可以恢复已删除的模型(如果这是您感兴趣的),这里是我使用的:

如果你真的想禁止批量删除,我会劝阻你采用这种方式:

  • 打破对申请行为的期望。如果我打电话给MyModel.objects.all().delete(),我希望之后表格为空。
  • 打破现有应用程序。

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

  

我猜这会涉及继承QuerySet并根据自己的喜好更改delete方法,继承默认管理器并让它使用您的自定义查询集,子类化模型 - 创建一个抽象模型并让它使用您的自定义管理器然后最后让你的所有模型子类化你的自定义抽象模型。