我遇到的情况类似于以下情况:
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
。理想情况下,我想使用子查询来执行此操作,但是我不知道如何编写它。该怎么办?
答案 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=...)