我有以下三个模型:
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
class PersonSession(models.Model):
start_time = models.DateTimeField(auto_now_add=True)
end_time = models.DateTimeField(null=True,
blank=True)
person = models.ForeignKey(Person, related_name='sessions')
class GameSession(models.Model):
score = models.PositiveIntegerFeild()
person_session = models.ForeignKey(PersonSession, related_name='games')
现在我想获取计算出他们获得的所有分数以及他们在所有游戏会话和分支会话中花费的时间的人员列表,我目前使用的查询如下:
Person.objects.annotate(game_score=Sum(Case(When(Q(sessions__games__isnull=True),
then=0),
default=F('sessions__games__score'),
output=models.PositiveIntegerField())))\
.annotate(spent_time=Sum(Case(When(Q(branch_sessions__isnull=False) &
Q(branch_sessions__end_time__isnull=False),
then=ExpressionWrapper(ExtractHour(ExpressionWrapper(F('sessions__end_time')-F('sessions__start_time'),
output_field=models.TimeField()),
output=models.PositiveIntegerField()) * 60 + \
ExtractMinute(ExpressionWrapper(F('sessions__end_time')-F('sessions__start_time'),
output_field=models.TimeField()),
output=models.PositiveIntegerField()),
output_field=models.PositiveIntegerField())),
default=0,
output=models.PositiveIntegerField()))) \
.annotate(total_score=F('game_score') + F('spent_time') * SCORE_MIN)\
.order_by('-total_score')
问题是该查询将所有表连接在一起,因此对于每个表,PersonSession
我们可能有很多GameSession
,并且结果表包含人员会话的重复行,这会导致人员会话的时间重复汇总并生成错误的结果。
在 sql 查询中,我必须首先构造一个包含游戏 socres 总和的子表,然后将该表与人员会话连接起来,但我不知道这在 django 中怎么可能?
我正在使用 django 1.11 和 postgres。