注释 Sum 会导致 None 而不是零

Posted

技术标签:

【中文标题】注释 Sum 会导致 None 而不是零【英文标题】:Annotating a Sum results in None rather than zero 【发布时间】:2011-09-03 21:01:53 【问题描述】:

我正在制作一个与您现在所在页面类似的 QA 网站。我试图按他们的分数对答案进行排序,但是没有投票的答案的分数设置为 None 而不是 0。这导致没有投票的答案位于页面底部的负面排名答案下方。当答案没有投票时,如何使注释分数为零?

这是我的模型:

from django.contrib.auth.models import User

Answer(models.Model):
    //some fields here
    pass

VOTE_CHOICES = ((-1, Down), (1, Up))

Vote(models.Model):
    user = models.ForeignKey(User)
    answer = models.ForeignKey(Answer)
    type = models.IntegerField(choices = VOTE_CHOICES)

    class Meta:
        unique_together = (user, answer)

这是我的查询:

answers = Answer.objects.filter(<something here>)
                        .annotate(score=Sum('vote__type'))
                        .order_by('-score')

编辑:为了清楚起见,我想在查询中执行此操作。我知道我可以把它变成一个列表,然后在我的 python 代码中对其进行排序,但如果可能的话,我想避免这种情况。

【问题讨论】:

仅供参考,有一个关于Sum() 的默认值的公开Django ticket。 【参考方案1】:

您可以使用django.db.models.functions 中的Coalesce function,例如:

answers = (Answer.objects
    .filter(<something here>)
    .annotate(score=Coalesce(Sum('vote__type'), 0))
    .order_by('-score'))

【讨论】:

具有讽刺意味的是,我猜这个答案对我来说是最底层的。 重要 如果没有找到行,coalesce 将返回 null。不幸的是,我必须找到另一个解决方案 @EugeneKovalev Coalesce 如果查询的值本身为空,则返回默认值。它不会评估整行,对吧? @EugeneKovalev 在没有行的情况下coalesce 返回null,您找到解决方案了吗? @EugeneKovalev 什么?不,它没有。【参考方案2】:

您使用自定义Manager 怎么样?例如:

AnswerManager(models.Manager):
    def all_with_score(self):
       qs = self.get_query_set().annotate(score=Sum('vote__type'))
       # Here, you can do stuff with QuerySet, for example
       # iterate over all Answers and set 'score' to zero if None.

Answer(models.Model):
    //some fields here
    objects = AnswerManager()

然后,你可以使用:

>>> answers = Answer.objects.all_with_score().order_by('-score')

【讨论】:

问题询问如何将内置 Sum 聚合函数的 None 值替换为 0。这不是这样做的

以上是关于注释 Sum 会导致 None 而不是零的主要内容,如果未能解决你的问题,请参考以下文章

2----JS的注释

零基础学python第三课, 程序的执行原理注释运算符

零基础学python第三课, 程序的执行原理注释运算符

Django - 注释多个 Sum() 对象会给出错误的结果

注释显示标注而不是开始拖放操作

java注释关键字与标识符