
Flask 的 Jinja2 模板中,{% set %} 声明的变量在循环内无法原地更新(因作用域限制),导致 x_value_weeks 始终保持初始值;正确做法是利用循环变量(如 loop.index0 或 range)直接计算动态坐标。
flask 的 jinja2 模板中,`{% set %}` 声明的变量在循环内无法原地更新(因作用域限制),导致 `x_value_weeks` 始终保持初始值;正确做法是利用循环变量(如 `loop.index0` 或 `range`)直接计算动态坐标。
Jinja2 模板引擎中,{% set %} 创建的变量具有块级作用域(block-scoped),且在模板渲染过程中是不可变绑定(immutable binding)——即每次 {% set x = x + 10 %} 实际上会创建一个新局部变量,而非修改外层同名变量。因此,在 for 循环中反复 set 同名变量并不会累积更新,最终所有 SVG 元素都会使用初始 x 值(如 5),造成定位重叠。
✅ 正确解法:避免状态维护,改用纯函数式表达式计算坐标。推荐以下两种方式:
方式一:基于 range 和索引计算(最清晰)
<svg class="user-streak-svg-container" xmlns="http://www.w3.org/2000/svg">
{% for week in range(weeks|length) %}
<svg class="user-streak-svg-column" x="{{ 5 + week * 10 }}"><!-- SVG 内容,例如:<rect width="8" height="40" fill="#4CAF50"/> --></svg>
{% endfor %}
</svg>
方式二:基于 loop.index0(适用于已存在的 weeks 列表)
<svg class="user-streak-svg-container" xmlns="http://www.w3.org/2000/svg">
{% for week in weeks %}
<svg class="user-streak-svg-column" x="{{ 5 + loop.index0 * 10 }}"><!-- SVG 内容 --></svg>
{% endfor %}
</svg>
? 注意事项:
- loop.index0 返回从 0 开始的当前迭代索引,比 loop.index(从 1 开始)更符合数组/偏移计算习惯;
- 若 weeks 是空列表,range(0) 或 loop.index0 均能安全处理,无需额外判空;
- 所有计算均在模板渲染时一次性完成,无副作用、无状态依赖,符合 Jinja2 的声明式设计哲学。
? 总结:Jinja2 不支持传统编程中的“变量递增”逻辑,应将坐标视为 f(i) = base + i × step 的数学映射关系,直接在属性中内联计算——简洁、可靠、易维护。











