如何在Jinja中遍历对象属性 避免硬编码Flask-SQLAlchemy模型字段
解决方案
方案1:后端预处理字段(更推荐,可控性更高)
先在视图层提前取出模型字段列表,和数据一起传给模板,避免模板层处理过多逻辑:
# 视图函数示例 from flask import render_template from your_app import db from your_app.models import Bean def bean_list(): # 取出Bean模型所有自定义字段名,可自定义过滤不需要展示的敏感/内部字段 bean_fields = [col.name for col in Bean.__mapper__.c if col.name not in ['要隐藏的字段名']] beans = Bean.query.all() # 把字段列表和数据共同传入模板 return render_template('some_page.html', beans=beans, bean_fields=bean_fields)
修改表头模板,不需要硬编码字段名:
<!-- some_page.html --> <table class="table"> <thead> <tr> {% for field in bean_fields %} <!-- 如果需要自定义显示名,可在后端维护字段->显示名的映射字典替换此处 --> <th scope="col">{{ field | title }}</th> {% endfor %} </tr> </thead> <tbody> {% for bean in beans %} {% include '_bean_info.html' %} {% endfor %} </tbody> </table>
行数据模板使用Jinja内置的attr过滤器动态读取对象属性,实现你需要的遍历效果:
<!-- _bean_info.html --> <tr> {% for field in bean_fields %} <td scope="row">{{ bean | attr(field) }}</td> {% endfor %} </tr>
该方案完全解耦模型和模板,后续你修改Bean模型的字段,只要调整字段过滤规则即可,不需要修改任何HTML代码。
方案2:模板层直接读取字段(无需修改后端代码)
如果不想调整后端逻辑,也可以直接在模板中读取SQLAlchemy模型的内置字段属性:
<!-- some_page.html --> <table class="table"> <thead> <tr> <!-- 注意要加非空判断,避免beans为空时报错 --> {% if beans %} {% for col in beans[0].__mapper__.c %} <!-- 同样可加if条件过滤不需要展示的字段 --> <th scope="col">{{ col.name | title }}</th> {% endfor %} {% endif %} </tr> </thead> <tbody> {% for bean in beans %} <tr> {% for col in bean.__mapper__.c %} <td scope="row">{{ bean | attr(col.name) }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table>
内容的提问来源于stack exchange,提问作者Jake Jackson
相关产品推荐
相关产品推荐

