Django中Google Chart针对datetime字段的for循环不生效问题
故障原因
- JS Date构造函数的月份索引规则和Django日期过滤器输出格式不匹配:JS接收的月份参数范围是0-11(0代表1月,11代表12月),而Django的
date:"m"输出的是1-12的自然月份,直接传入会导致日期计算错误,触发图表渲染异常。 - Google甘特图要求每行的Task ID为全局唯一值,你现有代码中所有行的Task ID都硬编码为
Introduction,重复ID会导致图表数据冲突无法正常渲染。 - 字符串字段未做JS转义处理:如果待办事项的名称、资源等字段包含单引号、换行符等特殊字符,会破坏JS数组的语法结构,引发JS执行报错。
- 你提供的
views.py代码中,render传入的上下文包含'team':team,但视图内没有定义team变量,如果模板中用到该变量会触发模板渲染错误。
修复方案
1. 模板JS部分修改
调整日期输出格式修正月份偏差,替换唯一Task ID,对字符串字段加转义处理,修改后代码如下:
function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Task ID'); data.addColumn('string', 'Task Name'); data.addColumn('string', 'Resource'); data.addColumn('date', 'Start Date'); data.addColumn('date', 'End Date'); data.addColumn('number', 'Duration'); data.addColumn('number', 'Percent Complete'); data.addColumn('string', 'Dependencies'); data.addRows([ {% for todo in todos %} [ '{{ todo.id|escapejs }}', '{{ todo.task_name|escapejs }}', '{{ todo.resource|escapejs }}', // 月份减1匹配JS Date规则 new Date({{ todo.start_date|date:"Y" }}, {{ todo.start_date|date:"n"|add:"-1" }}, {{ todo.start_date|date:"j" }}), new Date({{ todo.due_date|date:"Y" }}, {{ todo.due_date|date:"n"|add:"-1" }}, {{ todo.due_date|date:"j" }}), null, 50, // 可替换为todo实际进度字段 null ]{% if not forloop.last %},{% endif %} {% endfor %} ]); // 保留原有图表绘制、渲染逻辑 }
2. 可选更稳妥的日期处理方案
也可以直接在后端输出ISO格式日期,JS侧直接解析,避免手动处理月份的问题:
// 日期部分写法替换为 new Date("{{ todo.start_date.isoformat }}"), new Date("{{ todo.due_date.isoformat }}"),
3. views.py修正
删除未定义的team参数,或者补全team变量的查询逻辑:
def visualisation(request, project_id): project = Project.objects.get(id=project_id) counts_data = Todo.objects.aggregate( to_do_count=Count('id', filter=Q(status='to_do')), in_progress_count=Count('id', filter=Q(status='in_progress')), done_count=Count('id', filter=Q(status='done')) ) todos = project.todo_set.order_by('-project_code') # 要么删除team参数,要么补全team = xxx的查询逻辑 return render(request, 'todo_lists/progress.html', {"counts_data":counts_data,'todos':todos})
调试验证步骤
修改完成后打开浏览器开发者工具,切换到控制台标签页,查看是否有JS报错,同时可以查看渲染后的JS代码,确认new Date()内的参数符合预期。
内容的提问来源于stack exchange,提问作者Niki Grey
相关产品推荐
相关产品推荐

