
jinja2 模板中 `{% set %}` 声明的变量在 for 循环内无法真正“更新”,因其作用域为当前渲染上下文,每次 `{% set %}` 实际创建的是新局部变量。正确做法是直接基于循环索引(如 `loop.index0` 或 `range`)动态计算值。
在 Flask 的 Jinja2 模板中,{% set x_value_weeks = ... %} 语句看似可赋值,但 Jinja2 的变量绑定是不可变作用域(immutable scoping):在 for 循环内部使用 {% set %} 并不会修改外层同名变量,而是为该次迭代创建一个独立的、仅在当前块内有效的局部副本。因此,你观察到 x_value_weeks 始终保持初始值(如 5),后续的 {% set x_value_weeks = x_value_weeks + 10 %} 并未实现预期的累加效果。
✅ 正确且推荐的解决方案是避免状态维护,改用纯函数式表达式——利用循环变量或内置 loop 对象动态计算坐标:
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
✅ 推荐写法(基于 loop.index0)
<svg class="user-streak-svg-container" xmlns="http://www.w3.org/2000/svg">
{% set base_x = 5 %}
{% set step = 10 %}
{% for week in weeks %}
<svg class="user-streak-svg-column" x="{{ base_x + loop.index0 * step }}">
<!-- SVG content: e.g., <rect>, <circle>, etc. -->
<rect width="8" height="40" fill="#4CAF50" />
</svg>
{% endfor %}
</svg>? loop.index0 从 0 开始计数(第1次迭代为0,第2次为1…),因此 base_x + loop.index0 * step 精确生成 5, 15, 25, ... 序列。
✅ 替代写法(显式 range,适用于无数据源场景)
<svg class="user-streak-svg-container" xmlns="http://www.w3.org/2000/svg">
{% for i in range(weeks|length) %}
<svg class="user-streak-svg-column" x="{{ 5 + i * 10 }}">
<rect width="8" height="40" fill="#2196F3" />
</svg>
{% endfor %}
</svg>⚠️ 注意事项
- ❌ 不要依赖 {% set %} 在循环中“更新”变量——这是 Jinja2 的设计限制,非 bug;
- ✅ 优先使用 loop.index, loop.index0, loop.revindex 等内置属性,语义清晰且高效;
- ✅ 若需复用复杂计算逻辑,可提前在 Flask 视图中预处理(例如生成带 x_pos 属性的 week_items 列表),再传入模板,提升可读性与性能;
- ? 所有 x 值最终输出为字符串,确保单位(如 px)无需额外添加(SVG 的 x 属性默认单位为用户坐标,纯数字即可)。
通过消除模板中的状态依赖,代码更符合 Jinja2 的声明式范式,也更易测试、调试和维护。

















