代码之家  ›  专栏  ›  技术社区  ›  Carl G

相同的表Django ORM软删除方法可以吗?

  •  1
  • Carl G  · 技术社区  · 16 年前

    我使用以下设置在Django中实现软删除。我不是很熟悉的Django的引擎盖下,所以我很感谢任何反馈,对我可能遇到的问题。我特别不喜欢将QuerySet子类化。

    基本思想是 delete MyModel 变化 我的模型 date_deleted 删除 删除 QuerySet ,可以绕过对象的 删除 deleted_objects

    使用此设置需要定义 DeletionQuerySet DeletionManager 和添加 删除日期 , objects 删除的\u对象 到您的模型。

    谢谢,

    strongly discouraged

    class DeletionQuerySet(models.query.QuerySet):
    
        def delete(self):
            prev_deleted = self.filter(date_deleted__isnull=False)
            prev_deleted.actual_delete()
            prev_undeleted = self.filter(date_deleted__isnull=True)
            prev_undeleted.update(date_deleted=datetime.datetime.now())
    
        def actual_delete(self):
            super(DeletionQuerySet, self).delete()
    
    class DeletionManager(models.manager.Manager):
    
        # setting use_for_related_fields to True for a default manager ensures
        # that this manager will be used for chained lookups, a la double underscore,
        # and therefore that deleted Entities won't popup unexpectedly.
        use_for_related_fields = True
    
        def __init__(self, hide_deleted=False, hide_undeleted=False):
            super(DeletionManager, self).__init__()
            self.hide_deleted = hide_deleted
            self.hide_undeleted = hide_undeleted
    
        def get_query_set(self):
            qs = DeletionQuerySet(self.model)
            if self.hide_deleted:
                qs = qs.filter(date_deleted__isnull=True)
            if self.hide_undeleted:
                qs = qs.filter(date_deleted__isnull=False)
            return qs
    
    class MyModel(models.Model):
    
        # Your fields here...
        date_deleted = models.DateTimeField(null=True)
    
        #the first manager defined in a Model will be the Model's default manager
        objects = DeletionManager(hide_deleted=True)
        deleted_objects = DeletionManager(hide_undeleted=True)
    
        def delete(self):
            if self.date_deleted is None:
                self.date_deleted = datetime.datetime.now()
                self.save()
            else:
                super(Agreement, self).delete()
    
    1 回复  |  直到 16 年前
        1
  •  1
  •   gion    15 年前

    我认为任何与当前使用的,流行的,技术,没有办法有问题的领域不可知,通用的软删除。 我认为它更多地与历史/面向历史的数据库系统相联系,而不是与我们所使用的数据库系统相联系。

    你最有可能在我们的系统中出现的“删除”,在90%的情况下,是一个视觉删除。。。

    因为抱怨IsVisible、IsUnpublished(甚至IsDeleted)会把你的查询搞得一团糟,他们抱怨你必须始终小心地包含它们。。。

    但这显然是对域问题的忽视,如果域中有可以使其不可见或未发布的对象-当然,当您查询所有要显示的对象的列表时,您应该从一开始,查询所有不可见且未发布的对象,因为这是以完整形式解决域问题的方式。

    干杯。