如何让Jinja2对字符串内部嵌入的变量进行求值替换
核心原因
Jinja2 仅会解析模板顶层的 Jinja 语法标记,写在字符串字面量内部的 {{}} 占位符会被当成普通字符串处理,不会自动求值。
方案1:直接拼接变量(推荐,无额外依赖)
在定义 alarm_list 的 expr 字段时,不要把变量占位符写在字符串内部,使用 Jinja 字符串拼接运算符 ~ 直接拼接变量值,修改后的模板代码如下:
{% set oea_env = "dev" %} {% set oea_subsystem = "mysite" %} {% set crit_high_rh = 85 %} {% set alarm_list = [ { 'alert': 'No Temperature Readings', 'expr': '(container_humidity_rh{oea_asset_id=~".*:' ~ oea_env ~ ':' ~ oea_subsystem ~ ':service:1"} >= ' ~ crit_high_rh ~ ')' }] %} {% macro generate_alerts(alarm_list) %} {% for alarm in alarm_list %} - alert: {{ alarm.alert }} expr: {{ alarm.expr }} {% endfor %} {% endmacro %} # 代码后续部分: groups: - name: 'my-prometheus-alerts' rules: {{generate_alerts(alarm_list) }}
该方案不需要修改 Jinja 环境配置,直接运行即可得到期望输出。
方案2:二次渲染字符串(适用于expr来自外部数据源的场景)
如果你的 expr 字符串是从外部传入模板的(比如从数据库、配置文件读取,本身就自带 {{}} 占位符),可以自定义一个 Jinja 过滤器实现对字符串的二次求值:
- 首先在你的 Python 代码中注册自定义过滤器:
from jinja2 import Template, Environment def render_string(s, context): return Template(s).render(context) env = Environment() env.filters['render_str'] = render_string
- 在模板中使用过滤器渲染
expr:
{% macro generate_alerts(alarm_list) %} {% for alarm in alarm_list %} - alert: {{ alarm.alert }} expr: {{ alarm.expr|render_str(locals()) }} {% endfor %} {% endmacro %}
该方案可以自动解析字符串内部的所有 Jinja 占位符,不需要修改 expr 的原始内容。
内容的提问来源于stack exchange,提问作者Coherent
相关产品推荐
相关产品推荐

