Django模板for循环无法获取对象列表字段值的问题求助
问题原因分析及解决办法
我来帮你搞定这个问题!咱们先拆解下为啥页面没输出:
问题根源
你在视图里用了values_list()方法获取数据,这个方法返回的是元组的列表,而不是带键名的字典对象。举个例子,posts列表里的每一项其实是类似('shaina', 'austin')这样的元组——元组只能通过索引访问元素,根本没有firstname或surname这类属性,所以模板里用{{ post.firstname }}自然拿不到任何值,页面就空空如也啦。
解决办法
给你三个可行方案,按需选择:
方案1:改用values()方法(最推荐)
把视图里的values_list()替换成values(),这个方法会返回字典的列表,每个字典的键就是你指定的字段名,完美匹配模板里的写法:
class Student_list(View): def get(self, request): posts = Student.objects.all().values("firstname", "surname").union(Teacher.objects.all().values("firstname", "surname")) return render(request, "l4_UNION_queries/output.htm", context = {"posts": posts})
改完之后,模板里的{{ post.firstname }}和{{ post.surname }}就能正常渲染出数据了。
方案2:模板里按元组索引访问
如果不想修改视图代码,直接在模板里通过索引取值也可以——因为values_list()返回的元组顺序和你指定的字段顺序完全一致(第一个是firstname,第二个是surname):
<table> <tr> <th>First Name</th> <th>Surname</th> </tr> {% for post in posts %} <tr> <td>{{ post.0 }}</td> <td>{{ post.1 }}</td> </tr> {% endfor %} </table>
方案3:用namedtuple实现属性式访问(进阶)
如果你既想保留元组的轻量特性,又想用属性名访问元素,可以用collections.namedtuple把元组转换成带属性的对象:
from collections import namedtuple class Student_list(View): def get(self, request): # 定义命名元组,字段名和要取的字段对应 Person = namedtuple('Person', ['firstname', 'surname']) # 获取元组形式的查询集 student_posts = Student.objects.all().values_list("firstname", "surname") teacher_posts = Teacher.objects.all().values_list("firstname", "surname") # 把每个元组转换成命名元组对象 posts = [Person(*item) for item in student_posts.union(teacher_posts)] return render(request, "l4_UNION_queries/output.htm", context = {"posts": posts})
这样处理后,模板里的{{ post.firstname }}写法依然有效,同时还能享受元组的性能优势。
内容的提问来源于stack exchange,提问作者TAN YONG SHENG
相关产品推荐
相关产品推荐

