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

如何计算Django模型评论评分平均值并返回给REST API

实现方案

方案1:模型层新增计算属性(适合多处复用场景)

该方式将计算逻辑封装在Gigs模型中,所有调用Gigs实例的场景都可以直接复用计算逻辑,不需要重复编码。

# models.py
from django.db import models
from django.db.models import Avg

class Gigs(models.Model):
    # 保留你原有Gigs模型的全部字段,比如标题、价格、描述等
    title = models.CharField(max_length=120)
    # 其他原有字段...

    @property
    def average_rating(self):
        # 聚合计算关联评论的评分平均值
        avg_result = self.reviews.aggregate(avg=Avg('rating'))['avg']
        # 没有评论时默认返回0,可按需调整保留的小数位数
        return round(avg_result, 1) if avg_result else 0

class Reviews(models.Model):
    # 注意外键要设置related_name为reviews,和上面聚合时的调用名对应
    gig = models.ForeignKey(Gigs, on_delete=models.CASCADE, related_name="reviews")
    rating = models.SmallIntegerField() # 假设是1-5分的整数评分
    # 其他原有评论字段...

接下来修改序列化器,把平均评分字段加入返回值:

# serializers.py
from rest_framework import serializers
from .models import Gigs

class GigsSerializer(serializers.ModelSerializer):
    average_rating = serializers.FloatField(read_only=True)
    class Meta:
        model = Gigs
        # 把average_rating加入你原有fields列表即可,不需要修改其他逻辑
        fields = ['id', 'title', 'average_rating', ...]

注意:该方式查询Gigs列表时会产生N+1查询问题,更适合单条Gig详情接口的场景,如果是列表查询推荐用方案2。


方案2:视图层聚合查询(列表查询性能更优)

如果需要在Gigs列表接口返回平均评分,推荐在查询时一次性聚合所有数据,仅需要1次关联查询,性能远高于方案1。
不需要修改模型代码,直接调整视图层的查询集即可:

# views.py
from django.db.models import Avg
from rest_framework import viewsets
from .models import Gigs
from .serializers import GigsSerializer

class GigsViewSet(viewsets.ModelViewSet):
    # 原有查询集基础上增加annotate聚合逻辑
    queryset = Gigs.objects.all().annotate(
        average_rating=Avg('reviews__rating')
    )
    serializer_class = GigsSerializer

序列化器的修改和方案1完全一致,直接把average_rating加入序列化字段列表即可。

提示:如果需要固定返回小数位数,可以在序列化器字段中添加验证逻辑,或者用数据库函数直接在聚合时格式化结果。


验证效果

修改完成后调用Gigs的详情或列表接口,返回值中会自动新增average_rating字段,值为对应Gig的所有评论评分平均值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:27:01