You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历关联Album QuerySet的Review QuerySet并计算评分总和?

统计Album关联Review的评分总和

问题描述

我需要遍历与Album QuerySet关联的Review QuerySet,统计所有评分的总和(例如9+8+7+9=33)。模型定义如下:

class Album(models.Model):
    creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    artist = models.CharField(max_length=255)
    title = models.CharField(max_length=255)
    # image =
    rating = models.IntegerField(
        choices=[(i, i) for i in range(1, 11)],
        validators=[MaxValueValidator(10), MinValueValidator(1)],
        default=10,
    )
    ...

class Review(models.Model):
    reviewer = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    rating = models.IntegerField(
        choices=[(i, i) for i in range(1, 11)],
        validators=[MaxValueValidator(10), MinValueValidator(1)],
        default=10,
    )
    ...

我尝试了多个for循环但大多报错,只有Attempt 5返回了QuerySet,希望得到正确实现方法。

正确实现方法

方法1:Python层面遍历计算

如果数据量不大,可以直接遍历每个Album的Review集合,累加评分:

all_albums = Album.objects.all()
total_rating_sum = 0

for album in all_albums:
    # 遍历当前album的所有review,累加rating
    for review in album.review_set.all():
        total_rating_sum += review.rating

print(total_rating_sum)

或者用生成器表达式简化:

total_rating_sum = sum(review.rating for album in all_albums for review in album.review_set.all())

方法2:数据库层面聚合(更高效)

如果数据量较大,推荐用数据库聚合操作,减少Python和数据库的交互次数:

from django.db.models import Sum

# 统计所有Review的评分总和(关联所有Album)
total_sum = Review.objects.aggregate(total_rating=Sum('rating'))['total_rating'] or 0

# 如果需要按每个Album分别统计评分总和:
albums_with_review_sum = Album.objects.annotate(review_rating_sum=Sum('review__rating'))
for album in albums_with_review_sum:
    print(f"专辑《{album.title}》的评论评分总和:{album.review_rating_sum or 0}")

之前尝试的错误说明

  • album.review_set.rating.all():错误,review_set是管理器,不能直接访问rating字段,需要先调用.all()获取Review QuerySet,再遍历取rating。
  • album.review_set.filter("rating"):filter()需要传入关键字参数(如filter(rating__gte=5)),不能直接传字段名字符串。
  • album.review_set.get(rating)/album.review_set.get("rating"):get()用于获取单个对象,需要条件参数(如get(id=1)),不能直接传字段名,且如果有多个Review会报错。
  • Album.objects.get('review'):get()需要合法的查询条件,不能直接传关联模型名,语法错误。

内容的提问来源于stack exchange,提问作者Andrew Rea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:15:20