Django模板标签实现商品用户评分获取功能的问题
嘿,我来帮你搞定这个Django模板标签的问题!你的需求是在电商商品模板里获取当前用户对应商品的评分,现在的代码有几个关键问题需要修正,咱们一步步来:
1. 解决模板标签无法获取request的问题
你当前代码里直接用了request.user.id,但simple_tag默认不会传递请求上下文,必须声明takes_context=True才能拿到request对象。
2. 避免get()方法触发异常
如果用户还没给该商品评分,Rating.objects.get()会抛出DoesNotExist异常,直接导致页面崩溃,必须用更安全的方式查询。
修正后的模板标签代码
假设你的Rating模型有puntaje字段存储具体评分值,修正后的代码如下:
from django import template from .models import Rating register = template.Library() @register.simple_tag(takes_context=True) def puntaje_usuario(context, prod): # 从上下文里获取当前请求的用户 user = context["request"].user # 先处理匿名用户,避免未登录时出错 if not user.is_authenticated: return None # 用filter+first替代get,不存在时返回None而非抛出异常 rating_obj = Rating.objects.filter(usuario=user, producto=prod).first() # 有评分就返回分值,无评分返回None return rating_obj.puntaje if rating_obj else None
模板中的调用与星级展示
在商品模板里,你可以这样调用标签,并根据返回值渲染星级或提示信息:
<!-- 先加载你的模板标签库,假设标签文件名为rating_tags.py --> {% load rating_tags %} {% for producto in productos %} <div class="product-card"> <h2>{{ producto.nombre }}</h2> <!-- 调用标签并把结果存到变量里 --> {% puntaje_usuario producto as user_rating %} {% if user_rating %} <div class="star-rating"> <!-- 循环生成5颗星星,根据评分填充 --> {% for star in "12345" %} {% if star|int <= user_rating %} <span class="star filled">★</span> {% else %} <span class="star">☆</span> {% endif %} {% endfor %} </div> <p>你的评分:{{ user_rating }}</p> {% else %} <p>你还未对该商品进行评分</p> <!-- 这里可以添加跳转到评分页面的按钮/链接 --> {% endif %} </div> {% endfor %}
额外注意事项
- 确保Rating模型的外键字段名正确:
usuario要关联到Django的User模型,producto要关联到你的商品模型 - 如果你需要支持半星评分(比如4.5),可以调整星级渲染逻辑,用CSS控制半星样式
- 记得在
settings.py里把标签所在的app添加到INSTALLED_APPS,否则模板无法加载标签库
内容的提问来源于stack exchange,提问作者Federico Ribero




