Django查询集与GROUP BY

3 投票
1 回答
2361 浏览
提问于 2025-04-18 18:27

我在使用Django的查询集和GROUP BY查询时遇到了困难,我知道有很多类似的问题,但我真的搞不懂:/

我想创建一个类似于这个的请求(SQLite):

SELECT MAX(fb_game_score.value), fb_game_fbuser.first_name, fb_game_fbuser.last_name
FROM fb_game_score
JOIN fb_game_game ON (fb_game_score.game_id = fb_game_game.id)
JOIN fb_game_fbuser ON (fb_game_game.user_id = fb_game_fbuser.id)
GROUP BY fb_game_fbuser.fb_user_id;

这个查询很简单,它列出了用户的分数,只显示每个玩家的最佳分数。

为了更清楚,这里是模型类的定义:

class FBUser(AbstractUser):

    fb_user_id = models.CharField(max_length=100, null=True)
    oauth_token = models.CharField(max_length=1024, null=True)
    expires = models.IntegerField(null=True)
    highest_score = models.IntegerField(null=True)


class Game(models.Model):

    identifier = models.CharField(max_length=100, db_index=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='games')


class Score(models.Model):

    game = models.ForeignKey(Game, related_name='scores')
    value = models.IntegerField()
    date = models.DateTimeField(auto_now=True)
    timestamp = models.FloatField(default=0)
    inter = models.BooleanField(default=False)

1 个回答

4

在查询集中没有高级的 group_by 功能。它可以在调用 aggregateannotate 时使用,但你无法直接使用。

有一个低级的API,但完全没有文档说明。你可以获取一个内部查询的描述:

queryset = ... #whatever query you'd want to group by
query = queryset.query

然后你可以通过添加一个你想要分组的字段来修改 group_by 这个列表:

query.group_by.append('a_field')

但是:

  • 你必须非常清楚自己在做什么。
  • 这个API的稳定性没有保证。

目前的替代方案是使用原始的 SQL 查询(通过 django.db.connection.* 方法)。

编辑: 我刚看到一个 第三方应用,它可能会帮助你生成报告。我不确定你是否可以在代码中使用报告,还是只能在视图中使用(也就是说,不知道你是否可以在代码中处理报告,还是只能将其作为最终结果)。

撰写回答