使用Flask Jinja2渲染JSON为日期型表格时缺失日期如何处理
Jinja模板渲染缺省日期表格的可行实现思路
除了后端预处理数据的方案外,还有3种可落地的实现方式:
思路1:模板内实时构造日期映射字典
不需要修改后端传参逻辑,直接在模板层对每个接种中心的会话数据做结构转换,用日期作为键存储对应会话信息,后续遍历日期列时直接查表即可,是改动最小的方案。
<tbody> {% for center in centers %} <tr> <th scope="row"> <address> {{ center['name'] }} <br> {{ center['address'] }} </address> </th> {# 先构造当前中心的日期-会话映射字典 #} {% set session_map = namespace(data={}) %} {% for session in center.sessions %} {% set session_map.data[session.date] = session %} {% endfor %} {# 遍历日期列直接查表 #} {% for date in dates %} {% if date in session_map.data %} {% set s = session_map.data[date] %} <td> {{ s.available_capacity }} <br> {{ s.min_age_limit }} <br> {{ s.vaccine }} <br> </td> {% else %} <td>None</td> {% endif %} {% endfor %} </tr> {% endfor %} </tbody>
注:使用
namespace是为了避开Jinja的变量作用域限制,确保循环内对字典的更新能在循环外生效。
思路2:自定义Jinja过滤器做结构转换
如果不想在模板中编写过多业务逻辑,可以在后端定义一个轻量的Jinja过滤器,专门用于将会话列表转换为日期映射字典,模板层仅需调用过滤器即可,代码可维护性更高。
后端过滤器定义(Python)
def sessions_to_map(sessions): return {s['date']: s for s in sessions} # 注册过滤器到Jinja环境 app.jinja_env.filters['session_map'] = sessions_to_map
模板调用代码
<tbody> {% for center in centers %} <tr> <th scope="row"> <address> {{ center['name'] }} <br> {{ center['address'] }} </address> </th> {% set session_map = center.sessions | session_map %} {% for date in dates %} {% if date in session_map %} {% set s = session_map[date] %} <td> {{ s.available_capacity }} <br> {{ s.min_age_limit }} <br> {{ s.vaccine }} <br> </td> {% else %} <td>None</td> {% endif %} {% endfor %} </tr> {% endfor %} </tbody>
思路3:模板内嵌套循环匹配日期
如果单页展示的数据量很小(接种中心数≤50、日期列≤7天),可以直接在遍历日期时嵌套遍历当前中心的会话列表匹配对应日期,不需要额外做结构转换。
<tbody> {% for center in centers %} <tr> <th scope="row"> <address> {{ center['name'] }} <br> {{ center['address'] }} </address> </th> {% for date in dates %} {% set matched_session = None %} {% for s in center.sessions %} {% if s.date == date %} {% set matched_session = s %} {% endif %} {% endfor %} {% if matched_session %} <td> {{ matched_session.available_capacity }} <br> {{ matched_session.min_age_limit }} <br> {{ matched_session.vaccine }} <br> </td> {% else %} <td>None</td> {% endif %} {% endfor %} </tr> {% endfor %} </tbody>
原有实现的核心问题是默认sessions列表的顺序、长度和dates列表完全对齐,一旦某个中心缺少对应日期的会话,或是会话顺序和日期列顺序不一致,就会出现索引越界、匹配错误的问题,上述三种方案都可以规避这个问题。
内容的提问来源于stack exchange,提问作者Bhoopesh Sharma
相关产品推荐
相关产品推荐

