本文重点解决 Django 模板中因变量命名错误而导致 choice_text 无法正常显示的问题:在 {% for %} 循环里误把循环变量写成 question,结果后续使用 choice.choice_text 时变量实际上并未定义,页面最终只渲染出空的列表项。

本文主要说明 Django 模板中因变量名使用错误而造成 choice_text 无法渲染的常见问题:在 {% for %} 循环中错误地把循环变量命名为 question,导致后面调用 choice.choice_text 时找不到对应变量,因此页面只显示空的列表内容。
在 Django 模板里遍历外键反向关联对象时,例如 Question 对应多个 Choice,循环变量的名称必须和模板中实际引用的变量名保持完全一致。您当前这段模板代码中就存在一个典型且关键的语法与逻辑问题:
-
{% for question in question.choice_set.all %}
- {{choice.choice_text}} {% endfor %}
这里实际上包含两个明显错误:
- 循环变量被错误命名为
question(并且与外层的question对象同名),容易造成语义混乱以及变量覆盖; - 模板内部却在使用未声明的
choice变量({{choice.choice_text}}),而这个变量并没有在当前循环中定义。
✅ 正确的 Django 模板写法应当是:
{{ question.question_text }}
-
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }} {% endfor %}
? 关键点解析:
question.choice_set.all返回的是Choice模型实例组成的 QuerySet;for choice in ...会把每一个Choice对象依次赋值给变量choice;- 因此在 Django 模板中必须通过
choice.choice_text来读取字段,而不能写成choice_text,也不能误写为question.choice_text。
? 补充建议:
可以在视图函数中显式预取关联数据,以优化查询性能,尤其适合选项数量较多的场景:
from django.db import models def detail(request, question_id): question = get_object_or_404( Question.objects.prefetch_related('choice_set'), pk=question_id ) return render(request, "polls/detail.html", {'question': question})也可以在模板中加入空值判断,提高页面健壮性,避免没有数据时展示异常:
{% if question.choice_set.all %}-
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }} {% endfor %}
No choices a vailable.
{% endif %}
✅ 验证方法也很简单:启动 Django 开发服务器后,访问 /polls/1/,检查页面中的每个 标签是否都已经正确渲染出对应 Choice 的 choice_text,例如 “Not much” 或 “The sky” 这类文本内容。如果结果仍然为空,那么排查重点就不应只放在模板语法上,而是要进一步确认数据库中是否真的存在关联的 Choice 数据记录。您可以通过 Django Admin 后台或 shell 来进行核实。
牢记这一点:Django 模板中的变量作用域由 {% for %} 明确定义,变量命名就是使用约定——循环里定义什么名字,后续就必须严格使用这个名字。
