You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django传递字典至HTML中JS函数遇类型错误,求解决方案

解决Django字典传递到JS被识别为字符串的问题

你的问题核心在于:Django模板里的{{ t|escapejs }}把Python字典转换成了字符串形式,而不是JS能直接识别的对象。JS会把这个字符串当作普通文本处理,所以Object.keys(test)会返回字符串的字符索引,而不是字典的键。

下面是两种可靠的解决方法,推荐第一种更安全的方案:


方法1:使用Django的json_script模板标签(推荐)

Django内置的json_script标签会帮你把Python数据安全地序列化为JSON,并嵌入到页面中,避免XSS风险,同时能被JS正确解析。

步骤:

  1. 在HTML模板的任意位置(比如<script>标签外面)添加:
{{ t|json_script:"test-data" }}

这个标签会生成一个隐藏的<script>标签,ID为test-data,里面是格式化好的JSON字符串。

  1. 修改你的JS代码,解析这个JSON字符串为JS对象:
google.charts.load('current', {'packages':['table']});
google.charts.setOnLoadCallback(drawTable);

// 从json_script生成的标签中获取并解析数据
const test = JSON.parse(document.getElementById('test-data').textContent);
const key1 = Object.keys(test)[0];
const top1 = test[key1];

document.getElementById("demo").innerHTML = key1;

function drawTable() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Name');
  data.addColumn('number', 'Messages Amount');
  data.addRows([
    // 注意:如果top1是数字,需要转成字符串作为格式化显示值(f字段)
    [key1, {v: top1, f: top1.toString()}],
    ['Alice', {v: 12500, f: '$12,500'}],
    ['Bob', {v: 7000, f: '$7,000'}]
  ]);
  var table = new google.visualization.Table(document.getElementById('table_div'));
  table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});
}

方法2:在视图中提前序列化为JSON

如果你更习惯在后端处理,可以先把Python字典转成JSON字符串,再传递到模板:

步骤:

  1. 在Django视图中导入json模块,序列化字典:
import json
from django.shortcuts import render

def your_view(request):
    # 假设这是你的字典数据
    t = {"John": 12500, "Bob": 7000}
    # 序列化为JSON字符串
    t_json = json.dumps(t)
    return render(request, "your_template.html", {"t_json": t_json})
  1. 在模板的JS中直接使用这个JSON字符串(标记为safe避免转义):
google.charts.load('current', {'packages':['table']});
google.charts.setOnLoadCallback(drawTable);

// 直接使用序列化后的JSON,不需要引号,因为它本身就是JS对象格式
const test = {{ t_json|safe }};
const key1 = Object.keys(test)[0];
const top1 = test[key1];

document.getElementById("demo").innerHTML = key1;

function drawTable() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Name');
  data.addColumn('number', 'Messages Amount');
  data.addRows([
    [key1, {v: top1, f: top1.toString()}],
    ['Alice', {v: 12500, f: '$12,500'}],
    ['Bob', {v: 7000, f: '$7,000'}]
  ]);
  var table = new google.visualization.Table(document.getElementById('table_div'));
  table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});
}

为什么原来的代码不行?

{{ t|escapejs }}只是把Python字典的字符串表示(比如{'John': 12500})转成了JS安全的字符串,但它本质还是字符串。JS不会自动将这个字符串解析为对象,所以test的值是类似"{'John': 12500}"的文本,Object.keys(test)会返回字符串的每个字符的索引(比如["0", "1", "2"...]),test[key1]自然就拿到了单个字符。

内容的提问来源于stack exchange,提问作者user8163099

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:31:00