Django:使用limit子句对关系求和

时间:2019-06-26 16:58:12

标签: python django django-queryset

我遇到的情况类似于以下情况:

class Player(models.Model):
   pass

class Item(models.Model):
   player = models.ForeignKey(Player,
                              on_delete=models.CASCADE,
                              related_name='item_set')
   power = models.IntegerField()

我想用Player.objects.all()注释Sum(item_set__power),只考虑降序Item排序的前N个power。理想情况下,我想使用子查询来执行此操作,但是我不知道如何编写它。该怎么办?

1 个答案:

答案 0 :(得分:2)

这是使用原始查询集的解决方案(对我而言,它比使用ORM容易实现,但使用Subquery的ORM可能可以实现):

N = 2
query = """
SELECT id,
   (
       SELECT SUM(power) 
         FROM (SELECT power FROM myapp_item WHERE myapp_item.player_id = players.id ORDER BY power DESC LIMIT %s)
   )
   AS power__sum
FROM myapp_player AS players GROUP BY players.id
"""
players = Player.objects.raw(query, [N])

更新

RawQueryset无法添加注释,但是您可以使用RawSQL expression

from django.db.models.expressions import RawSQL

N = 2
queryset = Player.objects.all()
query2 = """
SELECT SUM(power) 
  FROM (SELECT  power FROM myapp_item WHERE myapp_item.player_id = myapp_player.id ORDER BY power DESC LIMIT %s)
"""
queryset.annotate(power__sum=RawSQL(query2, (N,)), my_annotation1=..., my_annotation2=...)