Django聚合选择

时间:2015-04-24 00:58:57

标签: django django-aggregation

我有以下型号:

class VotingRound(models.Model):
     pass # here are some unimportant fields

class Vote(models.Model):
     voting_round = models.ForeignKey(VotingRound)
     vote = models.CharField(choices=...)

现在我有VotingRound的实例,我想知道每个值代表了多少次。这很容易通过collections.Counter:

完成
>>> Counter(voting_round_instance.vote_set.values_list('vote', flat=True))
Counter({u'decline': 8, u'neutral': 5, u'approve': 4})

现在我想知道是否有办法用Django聚合技术做到这一点......

我找到了this module,但在使用它之前我想知道是否有原生方式来做它。

1 个答案:

答案 0 :(得分:6)

是的,你可以!

from django.db.models import Count
voting_round_instance.vote_set.values('vote') \
    .annotate(count=Count('vote')).distinct()

编辑:使用order_by()

您可能还需要确保默认排序不会弄乱您的聚合。使用相关对象管理器时尤其如此。

https://docs.djangoproject.com/en/1.8/topics/db/aggregation/#interaction-with-default-ordering-or-order-by

  

在选择输出数据时,将使用在查询集的order_by()部分中提及的字段(或在模型的默认排序中使用的字段),即使它们未在values()调用中另行指定。这些额外字段用于将“喜欢”结果组合在一起,并且它们可以使其他相同的结果行看起来是分开的。特别是在计算东西时会出现这种情况。

from django.db.models import Count
voting_round_instance.vote_set.values('vote') \
    .annotate(count=Count('vote')) \
    .distinct().order_by()