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

Django单商品平均评分渲染异常:显示所有商品而非指定商品

问题描述

尝试展示单个指定商品的用户平均评分,当前代码会渲染所有商品及其关联评分,而非仅目标商品。页面还需同时展示:

  • 单商品的平均评分(待修复)
  • 指定商品的所有用户评论(功能正常)

疑问:是否是评论功能导致的问题?是否需要在视图中关联product_id?如何修改?


相关代码

Models

class Product(models.Model):
    name = models.CharField('Product Name', max_length=120, null=True)
    class Meta:
        db_table='Product'
    def __str__(self):
        return str(self.name)

class ReviewRating(models.Model):
    user = models.ForeignKey(User,blank=True,on_delete=models.CASCADE)
    product=models.ForeignKey(Product,related_name="comments", on_delete=models.CASCADE)
    rating_1 = models.IntegerField(choices=RATING1,default=0)    
    def __str__(self):
        return '%s - %s - %s'%(self.user, self.product, self.date_added)

Views

from django.db.models import Avg
 
def Notes (request, product_id):
    product = Product.objects.get(pk=product_id)
    data = Product.objects.order_by('name').annotate(
        avg_rating_1 =Avg('comments__rating_1 '),

    return render(request, 'main/notes.html',{'product':product, 'data':data})

Template

{% for ReviewRating in data%}

{{ReviewRating.avg_rating_1 }}

{% endfor %}

问题原因及解决方案

问题原因

和评论功能无关,核心问题是视图中data = Product.objects.order_by('name').annotate(...)查询的是所有商品,并给每个商品加上平均评分,所以模板循环时会渲染所有商品的评分,而非仅目标商品。

修改方案

1. 优化视图代码(两种可选方式)

方式一:直接通过已获取的product对象计算平均评分

不需要额外查询所有商品,直接对当前商品的评论集求平均值:

from django.db.models import Avg
 
def Notes(request, product_id):
    product = Product.objects.get(pk=product_id)
    # 计算当前商品的平均评分,无评分时默认显示0
    avg_rating = product.comments.aggregate(avg_rating_1=Avg('rating_1'))['avg_rating_1'] or 0
    # 获取当前商品的所有评论(保留原有正常评论功能)
    comments = product.comments.all()
    return render(request, 'main/notes.html', {
        'product': product, 
        'avg_rating': avg_rating,
        'comments': comments
    })
方式二:过滤Product查询集到当前商品

如果坚持用annotate的方式,需要添加过滤条件限定到当前product_id:

from django.db.models import Avg
 
def Notes(request, product_id):
    product = Product.objects.get(pk=product_id)
    # 仅查询当前商品并标注平均评分
    data = Product.objects.filter(pk=product_id).annotate(
        avg_rating_1 = Avg('comments__rating_1')
    ).first()
    return render(request, 'main/notes.html', {'product': product, 'data': data})

2. 修改模板代码

因为只需要单个商品的评分,不需要循环遍历:

  • 对应方式一的模板:
<!-- 展示单个商品的平均评分 -->
<p>平均评分:{{ avg_rating }}</p>

<!-- 展示该商品的所有评论(保留原有正常逻辑) -->
{% for comment in comments %}
    <p>{{ comment.user }}:{{ comment.rating_1 }}分</p>
{% endfor %}
  • 对应方式二的模板:
<!-- 展示单个商品的平均评分 -->
<p>平均评分:{{ data.avg_rating_1 }}</p>

<!-- 评论部分保留原有正常逻辑 -->

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:09:22