Django中的多查询优化

时间:2018-07-18 09:54:14

标签: django django-models django-orm

我有三个模型,用户,成就和成就历史记录

用户模型看起来像

User(models.Model):
    name = models.CharField(max_length=255)

成就模型看起来像

Achievement(models.Model):
     name = models.CharField(max_length=255)

AchievementHistory模型如下

AchievementHistory(models.Model):
     achievement = models.ForeignKey(Achievement, on_delete=models.CASCADE)
     user = models.ForeignKey(user, on_delete=models.CASCADE)

我该如何计算用户的每一项成就。假设存在三项成就,例如“你好”,“世界”,“再见”,并且用户两次获得“你好”,世界获得了三次,那么我想要这样输出

{
    'hello': 2,
    'world': 3,
    'goodbye': 0,
}

我可以通过以下功能找到它

def get_user_achievements_by_id(id):
    user = User.objects.get(pk=id)
    response = []
    for achievement in Achievement.objects.all():
        number_of_entries = AchievementHistory.objects.filter(
            user=user, achievement=achievement).count()
        response.append({str(achievement.title): number_of_entries})
    return response

实际上,这里执行三个不同的查询。有什么方法可以减少查询数量,实际上可以减少一个查询。

1 个答案:

答案 0 :(得分:2)

您可以使用annotation。像这样:

error TS2554: Expected 1 arguments, but got 0.