Jinja2模板中如何区分字典列表与列表列表以适配表格渲染
嘿,我之前做项目的时候刚好碰到过一模一样的需求!Jinja2确实没法直接用Python的type()函数,但咱们可以用它内置的**测试器(tests)**来搞定类型判断,具体来说就是用is mapping来检测元素是不是字典(因为Python里的dict属于mapping类型)。
下面是适配两种数据格式的完整模板代码,我给你加了详细的注释:
{% block page_content %} <input type="text" id="search" placeholder="Type to search"> <table id="table" class="table"> <!-- 表头部分:区分字典列表和列表列表 --> <thead> <tr> {% if data and data[0] is mapping %} <!-- 情况1:数据是字典列表,用字典的key作为表头 --> {% for column_name in data[0].keys() %} <th>{{ column_name }}</th> {% endfor %} {% else %} <!-- 情况2:数据是列表列表 --> {% if headers %} <!-- 优先使用传入的自定义表头参数 --> {% for header in headers %} <th>{{ header }}</th> {% endfor %} {% elif data %} <!-- 如果没传表头,就用第一行数据当表头(可选,根据你的需求调整) --> {% for header_item in data[0] %} <th>{{ header_item }}</th> {% endfor %} {% endif %} {% endif %} </tr> </thead> <!-- 表格内容部分:同样区分两种数据格式 --> <tbody> {% for row in data %} <tr> {% if row is mapping %} <!-- 处理字典行:按表头的key依次取值 --> {% for column_name in data[0].keys() %} <td>{{ row[column_name] }}</td> {% endfor %} {% else %} <!-- 处理列表行:直接遍历每个元素 --> {% for cell in row %} <td>{{ cell }}</td> {% endfor %} {% endif %} </tr> {% endfor %} </tbody> </table> {% endblock %}
关键细节说明:
- 类型判断逻辑:用
data[0] is mapping替代type(data[0]) == dict,这是Jinja2推荐的方式,因为它还能兼容其他实现了mapping接口的自定义类型。 - 空数据处理:加了
{% if data %}的判断,避免数据为空时访问data[0]抛出错误。 - 列表列表的表头选项:我做了两种处理——要么让你在渲染模板时传入
headers参数(比如Flask里render_template('xxx.html', data=my_list_of_lists, headers=['姓名','年龄','邮箱'])),要么默认用第一行数据当表头,你可以根据自己的需求选一个,或者删掉其中一个分支。 - 遍历一致性:字典行的遍历用了
data[0].keys(),保证表头和内容的列顺序完全对应,不会出现列错位的问题。
这样不管你传入的是[{"name":"张三","age":25}, {"name":"李四","age":30}]还是[["张三",25], ["李四",30]],模板都能正确渲染出表格啦!
内容的提问来源于stack exchange,提问作者Josh Sharkey
相关产品推荐
相关产品推荐

