本文详解如何在 Django 视图中正确将 Python 数据结构序列化为标准 JSON 字符串(而非 Python 字面量),避免因单引号导致 JSON.parse() 失败,并推荐两种生产级方案:json.dumps() 手动序列化与 Django 内置 |json_script 模板过滤器。
本文详解如何在 django 视图中正确将 python 数据结构序列化为标准 json 字符串(而非 python 字面量),避免因单引号导致 `json.parse()` 失败,并推荐两种生产级方案:`json.dumps()` 手动序列化与 django 内置 `|json_script` 模板过滤器。
在 Django 开发中,常需将后端查询的数据(如用户体重记录)传递给前端 JavaScript 进行可视化渲染(例如使用 Chart.js 绘制趋势图)。但若直接在模板中通过 {{ weight_data|safe }} 渲染 Python 列表字典,Django 会输出类似 [{'weight': '122.00', 'entry_date': '2023-09-28'}] 的字符串——这不是合法 JSON:JSON 标准强制要求键名和字符串值必须使用双引号("),而 Python 的 repr() 输出默认使用单引号('),导致前端调用 JSON.parse() 时抛出 SyntaxError。
在视图中引入 Python 标准库 json,用 dumps() 显式生成符合 RFC 8259 的 JSON 字符串:
from json import dumps # ✅ 关键导入# ... 其他逻辑(分页、查询等)保持不变 ...# 替换原 serialized_data 赋值语句:serialized_data = dumps([ { 'weight': float(record.weight), # 推荐保留数值类型,避免后续 parseFloat() 'entry_date': record.entry_date.isoformat() # 更健壮的日期格式(ISO 8601) } for record in user_weight_log])
? 注意:dumps() 默认不转义 HTML 特殊字符。若数据含 <, >, & 等,建议添加 separators=(',', ':') 减少空格,并确保模板中仍使用 |safe(因 JSON 字符串本身不含 HTML 标签,安全)。
模板中保持原写法:
立即学习“Python免费学习笔记(深入)”;
<div id="weight-data" data-weight-data="{{ weight_data|safe }}"></div>
前端 JavaScript 可安全解析:
const weightDataElement = document.getElementById('weight-data');const weightDataJSON = weightDataElement.getAttribute('data-weight-data');const weightData = JSON.parse(weightDataJSON); // ✅ 成功!console.log(weightData[0].weight); // number: 122
Django 4.2+ 提供了更安全、更现代的解决方案:|json_script 过滤器。它自动序列化数据为 <script type="application/json"> 块,规避 XSS 风险且无需手动处理引号或转义。
视图中直接传入 Python 对象(无需 dumps):
# 视图中保持原始列表推导式(不调用 dumps)weight_data = [ {'weight': float(record.weight), 'entry_date': record.entry_date.isoformat()} for record in user_weight_log]return render(request, 'profile.html', { 'user_weight_log': user_weight_log, 'form': form, 'weight_data': weight_data # ✅ 传入原生 Python list/dict})
模板中使用 |json_script:
<!-- 生成一个带 ID 的 script 标签 -->{{ weight_data|json_script:"weight-data" }}
前端通过 JSON.parse() 读取:
// 自动查找 ID 为 "weight-data" 的 script 标签并解析其内容const weightData = JSON.parse(document.getElementById('weight-data').textContent);console.log(weightData.length); // ✅ 正确解析为数组
✅ 优势总结:
- ✨ 自动 HTML 转义,杜绝 XSS(即使数据含恶意脚本也不会执行);
- ? 语义化 <script type="application/json"> 符合规范;
- ? 无需在视图中导入 json,逻辑更清晰;
- ? 支持任意嵌套结构(dict/list/tuple/None/bool/int/float),无需手动处理类型。
通过以上任一方案,即可彻底解决单引号 JSON 解析错误,实现 Django 后端与前端 JavaScript 的安全、高效数据互通。