Django模板引入静态JS不生效 Chart.js图表不显示问题排查
问题根因
Django模板引擎默认仅解析后缀为.html的模板文件,存放在static目录下的JS、CSS、图片等静态资源会被原封不动返回给浏览器,不会执行任何模板语法替换。
你写在data_table.js里的Django模板标签{% for d in data%}、变量输出{{d.label}}/{{d.data}}不会被替换成后端传入的实际值,浏览器拿到的JS文件里仍然保留这些模板语法,直接触发JS语法错误终止执行——你之前没看到报错是因为没打开浏览器开发者工具的Console面板查看JS错误,不是真的无报错。
把JS代码直接写在HTML文件的script标签内时,代码属于模板文件的一部分,Django会正常渲染替换模板变量,浏览器拿到的是合法可执行的JS代码,因此图表可以正常渲染。你之前尝试把script标签移动到canvas后仍然不生效,和脚本加载顺序无关,核心问题就是静态JS文件内的Django模板语法不会被解析。
修复方案
你可以任选以下一种方式修复:
方案1:动态数据写入HTML全局变量,静态JS读取(推荐)
这种方式既保留静态JS文件的可缓存性,又能正常传递后端动态数据:
- 修改
data_table.html,在引入外部静态JS之前,先把后端传入的图表数据渲染为全局JS变量:
{% load static %} <!DOCTYPE html> <head> <link rel="stylesheet" href="{% static 'styles.css' %}" type="text/css"> <title>Data viewer</title> </head> <body> <canvas id="myChart" width="200" height="200"></canvas> <!-- 先在模板内渲染动态数据,挂载到全局作用域 --> <script> window.chartConfig = { labels: [{% for d in data %}'{{ d.label }}',{% endfor %}], values: [{% for d in data %}{{ d.data }},{% endfor %}] } </script> <!-- 静态JS放在数据定义之后引入,确保能读取到全局变量 --> <script type="text/javascript" src="{% static 'data_table.js' %}"></script> <p class="text">Picture:</p> <br> <img class="img" src="{% static 'bild.jpg' %}" alt="My image"> </body> </html>
- 修改静态文件
data_table.js,删除所有Django模板语法,直接读取全局变量初始化图表:
const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { type: 'line', data: { labels: window.chartConfig.labels, datasets: [{ label: '# of Votes', data: window.chartConfig.values, backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } });
方案2:简单场景直接内联JS
如果页面JS逻辑很少,不需要单独抽离静态JS文件,直接把图表初始化代码写在HTML中canvas标签后的script块内即可,这也是你已经验证过可以正常运行的方式。缺点是JS逻辑较多时会让HTML文件过于臃肿,且JS代码无法被浏览器缓存复用。
额外注意事项
- 你当前的HTML文件中没有引入Chart.js依赖库,之前内联JS能正常运行大概率是浏览器缓存了其他页面加载的Chart.js,正式部署时记得在自己的业务JS代码之前引入Chart.js文件,否则会触发
Chart is not defined的报错。 - 如果需要在静态JS中使用大量后端动态数据,也可以通过接口请求的方式获取JSON数据,不必全部写在全局变量中。
内容的提问来源于stack exchange,提问作者Jens
相关产品推荐
相关产品推荐

