注释 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 而不是零的主要内容,如果未能解决你的问题,请参考以下文章