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

如何在Django中将字典数据传递给Chart.js生成图表

Django + Chart.js 图表不显示问题修复方案

问题根源分析

你的代码存在以下几个核心问题:

  • 模板中错误使用data.keys/data.values,传递给JS的是数组而非单个分类名称/数量
  • 分类名称作为字符串未加引号,导致JS语法解析错误
  • 包含category: null和count:0的无效数据,干扰图表渲染
  • 颜色数组长度不足,部分分类无对应颜色
  • 饼图(doughnut类型)不需要配置y轴刻度,多余配置引发冲突
  • 可能缺少Chart.js和jQuery的依赖引入

分步修复代码

1. 优化视图查询(过滤无效数据)

修改视图中的get_context_data方法,过滤掉空分类和数量为0的无效记录:

class CategoryChartListView(generic.ListView):
    model = Book
    template_name= 'pages/chart_category.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 过滤空分类和数量为0的记录,同时可选合并大小写分类(比如python/Python)
        context["dictCategory"] = Book.objects.values('category')\
            .annotate(count=Count('category'))\
            .exclude(category__isnull=True)\
            .exclude(count=0)
        return context

如果需要合并大小写分类,可使用Lower函数统一转换后分组,具体代码见文末额外建议

2. 修正模板数据传递与图表配置

替换模板中的脚本部分,修复数据传递逻辑并优化图表配置:

{%block content%}
<canvas id="myChart" width="400" height="100"></canvas>  
{%endblock content%}

{%block scripts%}
<!-- 先加载依赖库,必须在自定义脚本之前 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>
$(document).ready(function(){
    var ctx = document.getElementById('myChart').getContext('2d');

    // 动态生成足够的颜色,避免分类过多时颜色不足
    const generateColors = (count) => {
        const bgColors = [];
        const borderColors = [];
        for(let i=0; i<count; i++){
            const r = Math.floor(Math.random()*255);
            const g = Math.floor(Math.random()*255);
            const b = Math.floor(Math.random()*255);
            bgColors.push(`rgba(${r}, ${g}, ${b}, 0.2)`);
            borderColors.push(`rgba(${r}, ${g}, ${b}, 1)`);
        }
        return {bgColors, borderColors};
    };

    // 从Django上下文提取有效数据
    const labels = [{%for data in dictCategory%}"{{ data.category|escapejs }}", {%endfor%}].filter(Boolean);
    const counts = [{%for data in dictCategory%}{{ data.count }}, {%endfor%}].filter(Boolean);
    const {bgColors, borderColors} = generateColors(labels.length);

    var myChart = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: labels,
            datasets: [{
                label: '书籍数量',
                data: counts,
                backgroundColor: bgColors,
                borderColor: borderColors,
                borderWidth: 1
            }]
        },
        // 饼图不需要坐标轴配置,清空即可
        options: {}
    });
});
</script>
{%endblock scripts%}

关键修改点说明

  1. 数据传递修正:直接使用data.category和data.count获取字段值,用|escapejs处理特殊字符,给字符串添加双引号确保JS正确解析
  2. 无效数据过滤:通过filter(Boolean)移除空的标签和数据条目
  3. 颜色动态生成:根据分类数量自动生成对应颜色,避免颜色不足
  4. 依赖引入:添加Chart.js和jQuery的CDN链接,确保依赖加载完整
  5. 配置精简:移除饼图不需要的y轴刻度配置,避免冲突

额外建议:合并大小写分类

如果需要将python和Python这类大小写不同的分类合并,可修改视图代码:

from django.db.models.functions import Lower

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context["dictCategory"] = Book.objects.annotate(lower_category=Lower('category'))\
        .values('lower_category')\
        .annotate(count=Count('lower_category'))\
        .exclude(lower_category__isnull=True)\
        .exclude(count=0)
    return context

模板中对应的标签改为data.lower_category即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:50:06