Jinja2 无法直接遍历 Pandas DataFrame 对象,需先将其转换为字典列表(如 to_dict('records')),才能在 HTML 模板中通过 {% for %} 正确访问字段值。
jinja2 无法直接遍历 pandas dataframe 对象,需先将其转换为字典列表(如 `to_dict('records')`),才能在 html 模板中通过 `{% for %}` 正确访问字段值。
在 Flask + Jinja2 开发中,一个常见误区是直接将 Pandas DataFrame 传递给模板——虽然 Python 后端能成功执行 render_template(),但 Jinja2 模板引擎并不原生支持 DataFrame 的迭代语法(如 row.employee_name)。你遇到的下拉框显示空白,正是因为 Jinja 尝试对 DataFrame 对象调用属性访问时失败,未抛出异常但也未渲染任何内容。
✅ 正确做法是:在视图函数中将 DataFrame 转换为标准 Python 数据结构。推荐使用 .to_dict('records') 方法,它会将每行转为一个字典,整体返回一个字典列表,例如:
[{"employee_name": "John"}, {"employee_name": "Sunny"}, {"employee_name": "Pal"}]
对应修改你的路由代码如下:
@app.route('/')
def home():
emplList = pd.read_sql_query("SELECT DISTINCT employee_name FROM employeeTBL", conn)
return render_template('app.html', employees=emplList.to_dict('records'))
随后,Jinja2 模板即可安全访问:
<select id="multipleSelect" multiple name="native-select" placeholder="Native Select" data-search="true" data-silent-initial-value-set="true">
{% for row in employees %}
<option value="{{ row.employee_name }}">{{ row.employee_name }}</option>
{% endfor %}
</select>
⚠️ 注意事项:
- 始终对模板变量使用双花括号 {{ ... }} 包裹,并确保属性名拼写与字典键完全一致(区分大小写);
- 避免在模板中执行复杂逻辑(如 .to_dict()),所有数据预处理应在视图层完成;
- 若需多列数据(如 id 和 name),.to_dict('records') 同样适用,Jinja 中可写作 {{ row.id }} 和 {{ row.employee_name }};
- 开启 debug=True 时,若模板报错(如 UndefinedError),说明键不存在——请先用 print(emplList.to_dict('records')[0]) 在后端验证数据结构。
掌握这一转换模式,即可稳定、高效地将 Pandas 查询结果注入 Jinja2 模板,实现动态表单、表格、选项列表等常见 Web 功能。










