【问题标题】:Django queryset filter based on number of childrenDjango查询集过滤器基于孩子的数量
【发布时间】: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,那么只有前两个应该在最后的查询集中。我该怎么做才能使评估的查询集在内存中只有前两个对象?

谢谢!

【问题讨论】:

    标签: python django django-orm django-filter


    【解决方案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) ,即使看起来有点乱也可以使用
    猜你喜欢
    • 2019-07-31
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    相关资源
    最近更新 更多