如何在Jinja2中赋值含单引号的字符串变量并生成合法JSON
问题:Jinja2渲染JSON时含单引号导致格式错误
输入Payload
{ "address": { "summary": "my home's address" } }
使用的Jinja2模板
{ "parent_elem": [{ "address": "{{DATA.address}}" }] }
现有实现代码
with open('payload.json') as payload_file: data = json.load(payload_file) # Load the Jinja2 environment env = Environment(loader=FileSystemLoader('.')) template = env.get_template('jinja_template.json') # Render the template with the variables output = template.render( DATA = data ) return json.loads(output)
问题现象
运行后触发json.decoder.JSONDecodeError: Expecting ',' delimiter错误,渲染出的非法JSON如下:
{ "parent_elem": [{ "address": "{'summary': "my home's address"}" }] }
原因是{{ DATA.address }}直接输出了Python字典的原始字符串表示(用单引号包裹键值),同时字符串里的home's单引号未转义,和外层JSON的双引号产生语法冲突,导致JSON格式完全非法。
解决方法
核心思路:不要直接输出Python对象的原始字符串,而是把Python对象序列化为合法的JSON格式字符串,从根源避免引号冲突和未转义的特殊字符。
方案1:Python代码中提前序列化
修改渲染参数,先用json.dumps()把address对象转成合法JSON字符串,再传入模板:
import json from jinja2 import Environment, FileSystemLoader with open('payload.json') as payload_file: data = json.load(payload_file) env = Environment(loader=FileSystemLoader('.')) template = env.get_template('jinja_template.json') # 提前把address序列化为标准JSON字符串 output = template.render( ADDRESS_JSON = json.dumps(data['address']) ) return json.loads(output)
对应模板修改为:
{ "parent_elem": [{ "address": {{ ADDRESS_JSON }} }] }
注意:模板里的
{{ ADDRESS_JSON }}不需要加双引号,因为json.dumps()已经会输出带双引号的合法JSON对象。
方案2:Jinja2模板中直接调用序列化
把Python的json模块传入模板上下文,在模板里直接对DATA.address进行序列化:
import json from jinja2 import Environment, FileSystemLoader with open('payload.json') as payload_file: data = json.load(payload_file) env = Environment(loader=FileSystemLoader('.')) template = env.get_template('jinja_template.json') # 将json模块传入模板,允许模板内直接调用序列化方法 output = template.render( DATA = data, json = json ) return json.loads(output)
对应模板修改为:
{ "parent_elem": [{ "address": {{ json.dumps(DATA.address) }} }] }
最终合法输出
两种方案都会生成符合JSON规范的结果:
{ "parent_elem": [{ "address": {"summary": "my home's address"} }] }
内容的提问来源于stack exchange,提问作者ankur jain
相关产品推荐
相关产品推荐

