【问题标题】:How to I automatically filter out is_deleted records in an associated table in Django?如何自动过滤掉 Django 关联表中的 is_deleted 记录?
【发布时间】:2020-09-27 03:07:42
【问题描述】:

我在 Django 中对我的一个模型使用软删除,并且我正在覆盖默认管理器以始终仅返回活动记录,使用类似:

class ActiveRecordManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(is_deleted=False)

class Tag(models.Model):
    is_deleted = models.BooleanField(default=False, db_index=True)
    objects = ActiveRecordManager()

class Photo(models.Model):
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, related_name="photos")
    objects = ActiveRecordManager()

一切正常。但是,当我这样做时:

tag = Tag.objects.get(pk=100)

然后我尝试获取相关的照片:

photos = tag.photos.all()

然后我得到被删除的照片。我只想返回 没有 删除的对象(所以我的常规 objects 列表。我正在阅读 Django 中的 _base_mangers ,这似乎可以控制这一点,但 the documentation 建议反对过滤掉对象:

如果您覆盖 get_queryset() 方法并过滤掉任何行, Django 将返回不正确的结果。不要那样做。一个经理 过滤结果 get_queryset() 不适合用作基础 经理。

但我不清楚我应该如何过滤这些结果。有什么想法吗?

更新:

我被要求解释这个问题与这个问题有何不同: How to use custom manager with related objects?

在这个 8 年前的问题中,他们提到了一种已弃用的方法。该已弃用的方法已被我在下面概述的方法 (base_managers) 所取代,根据文档我应该使用该方法。如果人们认为我应该使用它,你能详细说明一下吗?

【问题讨论】:

  • 这能回答你的问题吗? How to use custom manager with related objects?
  • 你是否也在使用任何 Queryset 类?还是只是一个经理?
  • @ArakkalAbu 在那篇文章中他们谈到了 use_for_related_fields,但这已被弃用,而应使用 base_manager_name。但正如我根据文档在我的帖子中解释的那样,我不应该在我的情况下使用它。还是我错了?
  • @ArunT 我不确定 Queryset 类是什么。你能详细说明一下吗?

标签: django


【解决方案1】:

为什么不使用自定义查询方法而不是覆盖管理器,因为它可能会产生问题,例如在管理页面中?


class ActiveModelQuerySet(models.QuerySet):

    def not_active(self, *args, **kwargs):
        return self.filter(is_deleted=True, *args, **kwargs)

    def active(self, *args, **kwargs):
        return self.filter(is_deleted=False, *args, **kwargs)


class Tag(models.Model):
    is_deleted = models.BooleanField(default=False, db_index=True)
    objects = ActiveModelQuerySet().as_manager()

class Photo(models.Model):
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, related_name="photos")
    is_deleted = models.BooleanField(default=False, db_index=True)
    objects = ActiveModelQuerySet().as_manager()

然后您可以根据需要过滤模型

tag = Tag.objects.active(pk=100)

deleted_tags = Tag.objects.not_active()

photos = tag.photos.active()

还请注意,您的所有模型中都需要 is_deleted 属性,这些模型具有像 Photo 这样的软删除功能

【讨论】:

  • 谢谢,我不知道这种特殊的做事方式!
猜你喜欢
  • 2013-08-25
  • 2023-03-23
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多