关于两步关系混乱的Django annotate()

时间:2018-04-09 19:01:12

标签: django django-queryset django-aggregation

我有以下3个型号:

Category:
  date_start
  date_end
  active: bool

Player:
  name: str
  age: int
  category = models.ForeignKey(Category)

PlayerContact:
  contact_result: int
  player = models.ForeignKey(Player)

在这种情况下,我有:

  • 2类别
  • 每个类别10名玩家
  • 每个类别中包含contact_result = 3
  • 的1到3位玩家

如何注释类别查询集以获得contact_result=3的玩家数量?

我试过这个:

Categories.objects.annotate(
    Count(
        'player', 
        filter=Q(player__playercontact__contact_result=3)
    )
) # returns all players for each Category

Categories.objects.annotate(
    Count('player__playercontact__contact_result')
) # returns players with a contact_result but it's not filtered

类似的东西:

<CategoryQuerySet [<Category: Category object>, <Category: Category object>]>

# where each Category object is annotated by the count() of Players with,
# a PlayerContact's contact_result = 3

2 个答案:

答案 0 :(得分:1)

而不是注释,尝试计数链接到过滤器

Categories.objects.filter(Q(player__playercontact__contact_result=3)).count()

答案 1 :(得分:0)

我最终这样做了:

cats_and_numbers = [(cat, PlayerContact.objects.filter(contact_result=3,
                    player__category_id=cat.id).count()) for cat in queryset]

不会将此标记为正确,因为我确信有合适的方法可以做到这一点。

修改

如果这实际上是最好的方法,我可能会创建一个管理员来减少视觉噪音,例如:PlayerContact.objects.denied() # denied is just a random word, to illustrate