Django将列表作为参数传递给JavaScript被读为字符串如何解决
Django传列表到外部JS被识别为字符串问题修复
问题根因
你当前的写法存在两个核心错误:
- 把内联JS变量定义代码写在了引入外部JS的
<script>标签的属性区域,这部分代码属于HTML标签属性范畴,根本不会被JS引擎执行 getAttribute()是DOM属性读取方法,所有HTML属性的返回值默认都是字符串类型,不可能直接获取数组、对象这类复杂数据类型
推荐修复方案(全局变量挂载法,适配Chart.js场景最方便)
第一步:修改views.py(可选优化,更安全)
提前把列表序列化为JSON格式,避免特殊字符导致JS语法错误,同时降低XSS风险:
import json def index(request): raw_data = [1, 2, 3, 4, 5] context = { "chart_data": json.dumps(raw_data) } return render(request, 'index.html', context)
第二步:修正HTML模板的脚本写法
把内联变量定义和外部JS引入拆成两个独立的script标签,严格保证执行顺序:先定义变量,再加载外部JS。
<!-- 第一块:内联脚本,把Django传入的数据挂载到window全局作用域 --> <script> window.lineChartConfig = { label: "fakelabel", // 这里Django会直接把序列化后的JSON内容输出为JS可识别的数组字面量 index: {{ chart_data|safe }} } </script> <!-- 第二块:等全局变量定义完成后,再引入外部Chart.js逻辑文件 --> <script src="{% static 'js/chart.js/linechart.js' %}"></script>
第三步:修改外部JS文件的读取逻辑
去掉原来的getAttribute写法,直接读取全局挂载的配置即可,拿到的index就是标准JS数组类型,可以直接传给Chart.js使用:
// 从全局作用域读取配置 const { label, index } = window.lineChartConfig; // 验证类型:控制台会输出true 代表是数组 console.log(Array.isArray(index)); // 后续正常写Chart.js初始化逻辑即可
备用方案(data属性传递法)
如果不想用全局变量,可以把数据存在DOM元素的data-*自定义属性上,读取后做JSON解析:
- HTML模板部分:
<div id="lineChartWrap" data-label="fakelabel" data-index="{{ chart_data|escapejs }}"> <canvas></canvas> </div> <script src="{% static 'js/chart.js/linechart.js' %}"></script>
- 外部JS部分:
const wrap = document.getElementById('lineChartWrap'); const label = wrap.dataset.label; // 读取属性值后解析为数组 const index = JSON.parse(wrap.dataset.index);
注意事项
- 脚本加载顺序不能调换,必须先完成变量赋值/属性写入,再执行依赖这些数据的外部JS代码
- 用
|safe过滤器前要确保数据是可信的,不要直接把未经过滤的用户提交内容用safe输出,避免XSS漏洞
内容的提问来源于stack exchange,提问作者solid
相关产品推荐
相关产品推荐

