如何在Django模板的for循环中统计布尔值数量以展示问题解决状态?
解决Django模板中统计分类下已解决/未解决问题数量的方法
嘿,我来帮你搞定这个统计需求!你之前尝试的count和forloop.counter没得到想要的结果,是因为用错了姿势。下面给你几个实用的方案,从最推荐的后端处理到模板内实现都有:
方案1:在模型中封装统计方法(最推荐)
把统计逻辑直接写到Category模型里,这样模板可以直接调用,代码复用性也强。修改你的模型:
class Category(models.Model): name = models.CharField(max_length=50) # 统计已解决的问题数量 def solved_questions_count(self): return self.question_set.filter(solved=True).count() # 统计该分类下的总问题数 def total_questions_count(self): return self.question_set.count()
然后在模板里就能直接用这些方法了,非常简洁:
{% for category in categories %} {{ category.name }} - {{ category.solved_questions_count }}/{{ category.total_questions_count }} questions solved {% for question in category.question_set.all %} {{ question.title }} {{ question.description }} {{ question.solved }} {% endfor %} {% endfor %}
方案2:在ListView中预处理统计数据
如果你不想修改模型,也可以在视图里提前计算好每个分类的统计值,放到上下文里:
class CategoryView(ListView): model = Category context_object_name = 'categories' def get_context_data(self, **kwargs): # 先获取默认的上下文 context = super().get_context_data(**kwargs) # 给每个分类添加统计属性 for category in context['categories']: category.solved_count = category.question_set.filter(solved=True).count() category.total_count = category.question_set.count() return context
模板里同样可以直接调用这些属性:
{% for category in categories %} {{ category.name }} - {{ category.solved_count }}/{{ category.total_count }} questions solved {% for question in category.question_set.all %} <!-- 问题展示内容 --> {% endfor %} {% endfor %}
方案3:直接在模板内实现(不推荐,仅作参考)
如果一定要在模板里写逻辑,可以用{% with %}标签结合QuerySet的count方法:
{% for category in categories %} {% with solved_count=category.question_set.filter(solved=True).count total_count=category.question_set.count %} {{ category.name }} - {{ solved_count }}/{{ total_count }} questions solved {% endwith %} {% for question in category.question_set.all %} <!-- 问题展示内容 --> {% endfor %} {% endfor %}
为什么你之前的尝试没成功?
- 你用
{{ question.count }}的时候,question是单个对象,它并没有count属性,所以其实是无效的(可能你误写成了question_set的count?),所以才会返回多个1(模板的容错处理导致)。 forloop.counter是循环的当前迭代次数,每次遇到未解决的问题就会打印当前的次数,所以会输出1、2、3...而不是总数。
总的来说,优先选方案1或2,符合Django MTV架构的设计思想,把业务逻辑放在后端,模板专注于展示。
内容的提问来源于stack exchange,提问作者barbaart
相关产品推荐
相关产品推荐

