Django查询集过滤器基于孩子的数量

Posted

技术标签:

【中文标题】Django查询集过滤器基于孩子的数量【英文标题】:Django queryset filter based on number of children 【发布时间】:2020-10-22 09:07:18 【问题描述】:

我正在使用 Django 过滤器来为我的项目做一些过滤。我有以下型号:

class Foo(models.Model):
    pass

class Bar(models.Model):
    foo = models.ForeignKey(Foo, models.CASCADE)

我的查询如下所示:

Foo.objects.filter(blah=blah)

我想缩小这个过滤器,只给我 Foo 对象,这些对象至少有 5 个通过 FK 连接的 Bar 对象。

所以,如果我有 3 个 Foo 对象,它们分别有 7、5 和 3 个 Bar 对象,它们都有自己的 id,那么只有前两个应该在最后的查询集中。我该怎么做才能使评估的查询集在内存中只有前两个对象?

谢谢!

【问题讨论】:

【参考方案1】:

您可以注释Bar 对象的数量,然后对这些对象进行过滤:

from django.db.models import Count

Foo.objects.annotate(
    nbar=Count('bar')
).filter(
    blah=blah,
    nbar__gte=5
)

【讨论】:

啊,这就是注释的工作原理。谢谢! SO 迟早会让我接受。 如果它是 Count("bar__diff_model") 也可以。我认为答案是肯定的。 @acw:是的,如果要统计与bar相关的模型,可以使用连续的下划线。因此,您将计算与该 Foo 对象相关的 bar 模型相关的 diff_models 的数量。 @acw ,根据 official documentation ,一旦将 Count("bar__diff_model") 作为位置参数添加到 annotate() ,您就可以使用新的默认字段名称过滤查询集(从 annotate() 调用生成) bar__diff_model__count,例如Foo.objects.annotate(Count("bar__diff_model")).filter(bar__diff_model__count__gt=123) ,即使看起来有点乱也可以使用

以上是关于Django查询集过滤器基于孩子的数量的主要内容,如果未能解决你的问题,请参考以下文章

Django 数据库操作

django基础知识之模型查询:

Django查询集QuerySet及两大特性

Django自递归外键过滤器查询所有孩子

Django - 按 CharField 值长度过滤查询集

Django数据操作