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

Django模板嵌套循环实现星级评分显示问题求助

解决Django模板中根据星级字符串显示对应数量星星的问题

问题原因

你的product_star是CharField类型,存储的是类似"3"这样的字符串。当你在模板中使用{% for i in product_review.product_star %}时,Django会迭代这个字符串的每个字符——因为"3"只有一个字符,所以只会循环1次,自然只显示1个星星。

解决方案

下面提供几种无需修改视图层的模板端解决方法:

方法1:循环5次并判断星级(最简便)

既然星级范围固定是1-5,我们可以直接循环5次,每次判断当前循环的序号是否小于等于存储的星级值(字符串直接比较即可,比如"1"<="3"在Python中是成立的),这样既能显示对应数量的实心星,也能自动填充剩余的空心星:

{% for product_review in product_review %}
<li>
  <div class="review-heading">
    <h5 class="name">{{product_review.product_reviewed_by}}</h5>
    <p class="date">{{product_review.product_review_date|date:"d M Y, g:i A"}}</p>
    <div class="review-rating">
      {% for star_num in "12345" %}
        {% if star_num <= product_review.product_star %}
          <i class="fa fa-star"></i>
        {% else %}
          <i class="fa fa-star-o empty"></i>
        {% endif %}
      {% endfor %}
    </div>
  </div>
  <div class="review-body">
    <p>{{product_review.product_review_message}}</p>
  </div>
</li>
{% endfor %}

顺便提一句,你原来的日期是硬编码的,可以用Django的date过滤器格式化product_review_date字段,比如上面的|date:"d M Y, g:i A"就能输出类似27 DEC 2018, 8:00 PM的格式。

方法2:自定义模板过滤器

如果以后需要调整星级范围,或者需要更灵活的迭代逻辑,可以自定义一个模板过滤器:

  1. 在你的Django应用下创建templatetags目录(记得添加空的__init__.py文件),然后新建custom_tags.py文件:
from django import template

register = template.Library()

@register.filter
def to_range(value):
    # 将字符串转为整数,生成对应长度的range对象
    try:
        return range(int(value))
    except (ValueError, TypeError):
        return range(0)
  1. 在模板顶部加载这个自定义标签:
{% load custom_tags %}
  1. 然后在循环中使用:
<div class="review-rating">
  {% for i in product_review.product_star|to_range %}
    <i class="fa fa-star"></i>
  {% endfor %}
  {% for i in product_review.product_star|add:"0"|add:"-5"|abs|to_range %}
    <i class="fa fa-star-o empty"></i>
  {% endfor %}
</div>

第二个循环计算出剩余的空心星数量,确保总共显示5个星星。

方法3:利用字符串填充技巧

不用自定义过滤器,借助Django内置过滤器实现:

<div class="review-rating">
  {% with star_count=product_review.product_star|add:"0" %}
    {% for i in "x"|rjust:star_count %}
      <i class="fa fa-star"></i>
    {% endfor %}
    {% for i in "x"|rjust:5|slice:star_count|length|add:"-5"|abs %}
      <i class="fa fa-star-o empty"></i>
    {% endfor %}
  {% endwith %}
</div>

|add:"0"把字符串转为整数,|rjust:star_count生成一个长度为star_count的字符串,循环它就能得到对应次数的实心星;第二个循环则计算需要的空心星数量。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:04:03