Django模板for循环内if语句执行失效、页面异常跳转问题求助
问题背景
我正在用Django搭建聊天机器人,功能是获取调查问卷的预设答案选项,给不同选项分配对应分值,累加所有得分后输出结果。
带预设答案的示例问题代码如下:
<select name="survey1-q" data-conv-question="你是否经常会把未来要发生的事往糟糕、甚至非常消极的方向想?"> <option value="survey1-never">从不</option> <option value="survey1-rarely">很少</option> <option value="survey1-sometimes">偶尔</option> <option value="survey1-often">经常</option> <option value="survey1-veryoften">非常频繁</option> </select>
我写的模板层循环加条件判断代码如下:
<!-- 循环计算问卷得分 --> {% for i in survey1-q%} {% if survey1-q is "从不"%} {{score}}={{score + 0}} {% elif survey1-q is "很少" %} {{score}}={{score + 1}} {%elif survey1-q is "偶尔"%} {{score}}={{score + 2}} {%elif survey1-q is "经常"%} {{score}}={{score + 3}} {%elif survey1-q is "非常频繁"%} {{score}}={{score + 4}} {%endif%} {% endfor %} <p>你的得分是 {{score}}</p>
实际运行时,答完问卷后聊天机器人没有输出{{score}}得分,反而自动跳回初始阶段重新询问第一道题,排查资料后没找到问题,求解决方案。
问题原因&修复方案
你的代码里存在多个语法和逻辑错误,直接导致模板渲染失败,触发页面重定向:
- 变量名非法:Django模板中变量名不能包含横杠
-,survey1-q会被模板引擎解析为survey1 减 q,直接触发语法错误。如果是表单提交的字段,建议你把字段名改成下划线格式survey1_q,或者通过request.POST.get('survey1-q')在视图层取值。 - 循环逻辑完全多余:
survey1-q是单个问题的返回值,属于不可迭代的字符串,对它做for循环本身就会报错。 - 模板赋值语法错误:
{{score}}={{score + 0}}这种写法只会把内容直接输出到页面,根本不会修改score变量的值。Django模板不支持直接修改变量,得分计算逻辑建议放到视图层处理,不要写在模板里。 - 相等判断语法错误:Django模板中判断值相等要用
==,is是用来判断两个对象是否为同一个内存实例,用来对比字符串完全不生效。 - 匹配对象错误:select表单提交的是
option的value值(比如survey1-never),不是option的文本内容,你拿文本内容和提交值匹配,永远匹配不上。
推荐解决方案(逻辑放视图层)
视图层处理代码示例:
from django.shortcuts import render def survey_result(request): # 初始化得分 score = 0 # 获取表单提交的答案 answer = request.POST.get('survey1-q', '') # 分值映射表,直接查字典比if判断更高效 score_map = { 'survey1-never': 0, 'survey1-rarely': 1, 'survey1-sometimes': 2, 'survey1-often': 3, 'survey1-veryoften': 4 } # 累加得分 score += score_map.get(answer, 0) # 把得分传到模板 return render(request, '你的模板路径.html', {'score': score})
模板层直接输出即可:
<p>你的得分是 {{score}}</p>
临时解决方案(非要在模板层处理)
如果必须在模板层计算,要用with标签和模板过滤器实现,注意先把字段名改成survey1_q:
<!-- 提前从视图层把score_map传到模板是最优方案,下方字符串转映射只是临时兼容写法 --> {% with score_map="survey1-never:0,survey1-rarely:1,survey1-sometimes:2,survey1-often:3,survey1-veryoften:4"|split:"," %} {% for key_val in score_map %} {% set key, val = key_val.split(':') %} {% if survey1_q == key %} {% with score=val|add:score %} {% endwith %} {% endif %} {% endfor %} <p>你的得分是 {{score}}</p> {% endwith %}
内容的提问来源于stack exchange,提问作者Trang Pham Quynh
相关产品推荐
相关产品推荐

