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:自定义模板过滤器
如果以后需要调整星级范围,或者需要更灵活的迭代逻辑,可以自定义一个模板过滤器:
- 在你的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)
- 在模板顶部加载这个自定义标签:
{% load custom_tags %}
- 然后在循环中使用:
<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
相关产品推荐
相关产品推荐

