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

Django 3.2中如何关联Profile与Rating模型返回带评分的列表

解决方案:在Django中关联Profile与Rating模型并返回带评分的列表

针对你的需求,有两种常见实现方式,分别对应「返回平均评分」和「返回所有关联评分」的场景,以下是具体操作:

一、为每个Profile添加平均评分(推荐用于展示整体评分)

1. 修改查询集,计算平均评分

在profiles/views.py中,导入聚合函数并修改查询集,过滤掉已删除的评分后计算平均星级:

from django.db.models import Avg, Q

# ... 其他代码保持不变
profiles_queryset = Profile.objects.nearby_ground_list(coordinates).annotate(
    # 计算有效评分的平均值,is_remove=False过滤已删除的评分
    average_rating=Avg('rating__stars', filter=Q(rating__is_remove=False))
)

2. 更新序列化器,添加平均评分字段

在profiles/serializers.py中,为ProfileSerializer新增average_rating字段:

from rest_framework import serializers
from .models import Profile

class ProfileSerializer(serializers.ModelSerializer):
    # 只读字段,对应查询集annotate的结果,默认值避免无评分时返回null
    average_rating = serializers.FloatField(read_only=True, default=0.0)
    
    class Meta:
        model = Profile
        # 列出你需要返回的Profile字段,加上average_rating
        fields = ['id', 'name', 'owner', 'is_premium', 'average_rating']

二、返回每个Profile的所有关联评分

如果你需要展示所有用户对该Profile的评分列表,可以用预加载关联数据的方式避免N+1查询问题:

1. 优化查询集,预加载有效评分

在profiles/views.py中,导入Prefetch并修改查询集:

from django.db.models import Prefetch
from ratings.models import Rating

# ... 其他代码保持不变
profiles_queryset = Profile.objects.nearby_ground_list(coordinates).prefetch_related(
    # 预加载未删除的评分,并将结果存到valid_ratings属性中
    Prefetch('rating_set', queryset=Rating.objects.filter(is_remove=False), to_attr='valid_ratings')
)

2. 嵌套序列化器,返回评分列表

在profiles/serializers.py中,定义评分序列化器并嵌套到Profile序列化器中:

from rest_framework import serializers
from .models import Profile
from ratings.models import Rating

class RatingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Rating
        fields = ['user', 'stars', 'create_time']

class ProfileSerializer(serializers.ModelSerializer):
    # 嵌套评分序列化器,many=True表示多个评分
    valid_ratings = RatingSerializer(many=True, read_only=True)
    
    class Meta:
        model = Profile
        fields = ['id', 'name', 'owner', 'is_premium', 'valid_ratings']

额外优化建议

为了让反向关联更直观,建议修改ratings/models.py中的外键字段,添加related_name:

profile = models.ForeignKey(Profile, verbose_name=_(\"profile\"), on_delete=models.CASCADE, related_name='ratings')

之后你就可以用profile.ratings代替默认的profile.rating_set,代码可读性更强。

注意点

  • 你的现有代码中,GET请求使用request.data获取参数是错误的,GET请求参数应该用request.query_params,否则无法正确获取到coordinates参数。
  • 代码中kind变量未定义,需要补充定义或移除相关代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:41:18