首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django注释按谓词和计数结果的查询集

Django注释按谓词和计数结果的查询集
EN

Stack Overflow用户
提问于 2021-12-03 21:55:43
回答 2查看 39关注 0票数 0

我有两个模型:

代码语言:javascript
运行
复制
class Game(models.Model):
    id = models.AutoField(primary_key=True)


class Score(models.Model):
    id = models.AutoField(primary_key=True)
    game = models.ForeignKey(Game, related_name="score", on_delete=models.CASCADE)
    first_score = models.IntegerField(blank=True)
    second_score = models.IntegerField(blank=True)
    is_rusk = models.BooleanField(blank=True)

我得到了一个游戏对象的查询集:

代码语言:javascript
运行
复制
[
    {
        "id": 314317035,
        "score": [
            {
                "first_score": 5,
                "second_score": 1,
                "is_rusk": false
            }
        ]
    },
    {
        "id": 311298177,
        "score": [
            {
                "first_score": 5,
                "second_score": 2,
                "is_rusk": false
            }
        ]
    },
    {
        "id": 310278749,
        "score": [
            {
                "first_score": 5,
                "second_score": 2,
                "is_rusk": false
            }
        ]
    },
    {
        "id": 309866238,
        "score": [
            {
                "first_score": 5,
                "second_score": 0,
                "is_rusk": true
            }
        ]
    },
    {
        "id": 307926664,
        "score": [
            {
                "first_score": 5,
                "second_score": 0,
                "is_rusk": true
            }
        ]
    },
    {
        "id": 306047964,
        "score": [
            {
                "first_score": 4,
                "second_score": 5,
                "is_rusk": false
            }
        ]
    },
    {
        "id": 304881611,
        "score": [
            {
                "first_score": 5,
                "second_score": 3,
                "is_rusk": false
            }
        ]
    },
    {
        "id": 304468136,
        "score": [
            {
                "first_score": 5,
                "second_score": 2,
                "is_rusk": false
            }
        ]
    },
]

我想用rusks_cnt注释这个查询集,它将是使用is_rusk=True的对象计数,如果有一种方法可以不将它添加到每个对象,就像一个字段一样,那也会很好。

我认为最简单的方法是:

代码语言:javascript
运行
复制
cnt = queryset.filter(score__is_rusk=True).count()

但是当我尝试这样注释的时候:

代码语言:javascript
运行
复制
cnt = queryset.filter(score__is_rusk=True).count()
queryset = queryset.annotate(cnt=cnt)

上面写着:

QuerySet.annotate() received non-expression(s): 2.

我也尝试过:

代码语言:javascript
运行
复制
queryset = queryset.annotate(
         rusk_cnt=Sum(
                Case(When(score__is_rusk=True, then=1)), output_field=IntegerField()
            )
        )

但结果是:

代码语言:javascript
运行
复制
[
    {
        "id": 279658929,
        "rusk_cnt": 1
    },
    {
        "id": 279796553,
        "rusk_cnt": null
    },
    ...
]

我还想知道仅仅使用.count()会导致糟糕的性能吗?

EN

回答 2

Stack Overflow用户

发布于 2021-12-03 22:07:38

Annotate用于对每个条目进行计算。如果您想要计算整个查询集,请使用聚合。

Difference between Django's annotate and aggregate methods?

票数 1
EN

Stack Overflow用户

发布于 2021-12-03 22:04:34

您可以使用Value进行注释

代码语言:javascript
运行
复制
from django.db.models import Value

cnt = queryset.filter(score__is_rusk=True).count()
queryset = queryset.annotate(cnt=Value(cnt))

但是这将添加相同的值:将queryset中的GameScore对象的数量添加到所有Game对象中,这没有多大意义。

如果您要使用Game True Score is_rusk=True中的对象数量来注释对象,可以使用:

代码语言:javascript
运行
复制
from django.db.models import Q, Sum

queryset.annotate(
    rusk_cnt=Sum('score', filter=Q(score__is_rusk=True))
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70221083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档