Django中向Google Charts表格传递元组无法渲染问题求助
问题根因
Google Charts的data.setCell()方法不支持直接传入整行元组作为参数,该方法要求的入参格式为setCell(行索引, 列索引, 单元格值),你直接传入整个三元组相当于只传了一个参数,完全不符合方法的调用要求,所以表格无法正常渲染。
同时Django模板直接遍历渲染data.setCell(company)后,生成的JS代码为data.setCell(('Facebook', 384.33, 244.61)),属于语法错误的调用格式,也会导致代码执行中断。
解决方案
方案1(更推荐):直接用addRows批量加载整行数据
这种方法不需要手动遍历设置每个单元格,代码更简洁不易出错。
- 先在views.py中将
data_cell转为JSON字符串传入模板:
import json def your_view(request): # 你的业务逻辑,生成data_cell元组列表 data_cell = [('Facebook', 384.33, 244.61), ('Google', 2903.81, 2085.12)] context = { "data_cell": json.dumps(data_cell) } return render(request, "你的模板文件名.html", context)
- 修改JS代码直接加载JSON数据:
function drawTable() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Company Name'); data.addColumn('number', '52 week high'); data.addColumn('number', '52 week low'); // 直接解析Django传入的JSON数据作为行数据 var rowData = JSON.parse('{{ data_cell|escapejs }}'); data.addRows(rowData); var table = new google.visualization.Table(document.getElementById('table_div')); table.draw(data, {showRowNumber: true, width: '50%', height: '50%'}); google.visualization.events.addListener(table, 'select', function() { var row = table.getSelection()[0].row; alert('You selected ' + data.getValue(row, 0)); }); }
方案2:坚持使用setCell的修正写法
如果必须用setCell实现,需要遍历的时候同时拿到行索引,分别给三个列的单元格赋值:
function drawTable() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Company Name'); data.addColumn('number', '52 week high'); data.addColumn('number', '52 week low'); // 动态根据数据长度添加对应行数,不要写死为5 data.addRows({{ data_cell|length }}); {% for row_idx, company in data_cell %} // 分别设置每行三列的单元格值 data.setCell({{ row_idx }}, 0, '{{ company.0|escapejs }}'); data.setCell({{ row_idx }}, 1, {{ company.1 }}); data.setCell({{ row_idx }}, 2, {{ company.2 }}); {% endfor %} var table = new google.visualization.Table(document.getElementById('table_div')); table.draw(data, {showRowNumber: true, width: '50%', height: '50%'}); google.visualization.events.addListener(table, 'select', function() { var row = table.getSelection()[0].row; alert('You selected ' + data.getValue(row, 0)); }); }
注意事项
- 字符串类型的数值在模板渲染时要加引号,数值类型不需要,避免JS语法错误。
- 字符串变量用
escapejs过滤器比safe过滤器更安全,能避免特殊字符导致的代码注入或语法错误。 - 不要把行数写死为固定值,动态用数据长度设置能避免数据行数不匹配的问题。
内容的提问来源于stack exchange,提问作者Mati
相关产品推荐
相关产品推荐

