
Django 模板中遍历 ForeignKey 反向关系时,需确保 for 循环的变量名与模板中引用的变量名一致;当前问题源于循环变量误写为 question,导致后续使用未定义的 choice 变量而无法渲染文本。
django 模板中遍历外键反向关系时,需确保 `for` 循环的变量名与模板中引用的变量名一致;当前问题源于循环变量误写为 `question`,导致后续使用未定义的 `choice` 变量而无法渲染文本。
在 Django 中,当一个模型(如 Choice)通过 ForeignKey 关联到另一个模型(如 Question)时,Django 会自动为 Question 实例提供 choice_set 属性,用于访问所有关联的 Choice 对象。但在模板中遍历时,循环变量名必须与实际使用的变量名严格匹配。
你当前的模板代码存在两处关键错误:
-
{% for question in question.choice_set.all %}
- {{choice.choice_text}} {% endfor %}
- 第一行中,
{% for question in ... %}将每个Choice实例错误地赋值给变量question(覆盖了外层传入的Question对象),造成语义混乱; - 第二行中,
{{ choice.choice_text }}却试图访问一个从未声明的choice变量,Django 模板引擎会静默忽略该表达式(不报错但输出为空),因此仅显示空<li>元素(即可见的项目符号,无文字)。
✅ 正确写法应统一使用有意义且一致的变量名,例如 choice:
<h1>{{ question.question_text }}</h1>
-
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }} {% endfor %}
? 提示:Django 模板对变量名大小写敏感,且不会抛出“未定义变量”异常,而是默认渲染为空字符串——这使得此类错误难以察觉,务必仔细核对循环变量命名。
此外,为提升可读性与健壮性,建议在模板中添加空值判断(尤其在开发初期数据可能不完整时):
{% if question.choice_set.all %}
-
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }} {% endfor %}
No choices available.
{% endif %}最后,请确认数据库中确实存在关联的 Choice 数据(可通过 Django Admin 或 Shell 验证):
# 在 manage.py shell 中执行 from polls.models import Question q = Question.objects.get(id=1) q.choice_set.all() # 应返回 QuerySet,如 [<choice: ...>, ...]</choice:>
只要变量名一致、数据存在、字段名正确(choice_text),choice_set 反向查询即可正常工作。这是 Django ORM 反向关系渲染中最常见也最易被忽视的细节之一。











