外键的Django组和另一个字段的总和过滤

时间:2014-05-23 18:30:25

标签: django django-models django-queryset

鉴于模型:

class Bid(models.Model):
    account = models.ForeignKey('accounts.Account', related_name="bids")
    tokens = models.IntegerField(default=0)

我希望能够做两件事。

  1. 获取每个帐户的代币总和。
  2. 根据令牌总和过滤帐户。
  3. 因为我希望能够以其他方式动态过滤结果,所以获得一个我可以继续过滤的查询集会很棒。提前谢谢。

1 个答案:

答案 0 :(得分:3)

您可以annotate()使用generate aggregates for each item in a QuerySet。来自Django Docs:

  

可以使用annotate()子句生成每个对象的摘要。 当指定annotate()子句时,QuerySet中的每个对象都将使用指定的值进行注释。

     

aggregate()不同,annotate()不是终止子句。 annotate()子句的输出是QuerySet ;可以使用任何其他QuerySet操作修改此QuerySet,包括filter()order_by(),甚至是对annotate()的其他调用。

参考您的示例,您应该可以使用以下内容来过滤具有令牌总数> = 100 的帐户:

from django.db.models import Sum

# every Account in the Queryset will have an extra attribute called sum_tokens
qs1 = Account.objects.annotate(sum_tokens=Sum('bids__tokens'))

# annotate returns a QuerySet so you can continue to filter it
qs2 = qs1.filter(sum_tokens__gte=100)

# combine the above two to get what you need
qs = Account.objects.annotate(sum_tokens=Sum('bids__tokens')).filter(sum_tokens__gte=100)