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

使用Django与Chart.js实现按公司类型统计数量并展示饼图时无法显示饼图的问题排查

Django + Chart.js 饼图无法显示的问题排查与修复

问题背景

我需要统计CompanyType模型下各类型的公司数量并通过饼图展示,统计依据是Company表的name字段。已经完成了Django模型和视图的编写,但前端引入Chart.js后饼图始终无法显示,怀疑是前端脚本存在问题。

相关代码如下:

models.py

class CompanyType(models.Model):
    company_type = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)
    created_at = models.DateField(auto_now_add=True)
    updated_at = models.DateField(auto_now=True)

class Company(models.Model):
    name = models.CharField(max_length=100)
    address = models.TextField()
    company_type = models.ForeignKey(CompanyType,on_delete=models.CASCADE)
    is_active = models.BooleanField(default=True)

views.py

def index(request):
    labels = []
    data = []
    queryset = Company.objects.values('company_type__company_type').annotate(company_type_sum=Count('name')).order_by('-company_type_sum')
    for entry in queryset:
        labels.append(entry['company_type__company_type'])
        data.append(entry['company_type_sum'])
    context = {
        'labels':labels,
        'data':data,
    }
    return render(request,'index.html',context)

index.html 脚本部分

<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
    type: 'pie',
    data: {
        labels: [data.labels],
        datasets: [{
            label: 'Companies in Particular Section',
            data: [data.data],
            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
            }
        }
    }
});
</script>

排查出的问题

  1. Django模板变量引用错误:在JS中直接写[data.labels]是完全错误的,Django的上下文变量需要通过模板语法{{ }}输出,而且后端传递的labels和data本身已经是数组,不需要额外用[]包裹,否则会导致Chart.js拿到的是嵌套数组,无法正确解析。
  2. 饼图不需要坐标轴配置:你的options里添加了scales配置,但饼图类型没有坐标轴,这个配置不仅多余,还可能干扰Chart.js的渲染逻辑。
  3. 缺少必要的Canvas元素:虽然你没提到,但如果页面上没有id为myChart的<canvas>元素,JS会找不到渲染容器,饼图自然无法显示。

修复方案

1. 修正前端脚本中的变量引用和配置

修改index.html中的脚本部分,正确引用Django模板变量,并移除无用的坐标轴配置:

<!-- 首先确保页面上存在这个Canvas元素 -->
<canvas id="myChart" width="400" height="400"></canvas>

<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
    type: 'pie',
    data: {
        // 直接输出Django传递的数组,用|safe确保格式正确
        labels: {{ labels|safe }},
        datasets: [{
            label: 'Companies in Particular Section',
            data: {{ data|safe }},
            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
        }]
    },
    // 移除scales配置,饼图不需要坐标轴
    options: {}
});
</script>

2. 可选优化:简化视图层代码

你的视图里手动遍历queryset组装labels和data可以简化,直接用Django的聚合结果来生成:

def index(request):
    queryset = Company.objects.values('company_type__company_type').annotate(count=Count('name')).order_by('-count')
    # 直接从queryset中提取数据,不需要手动循环
    labels = [item['company_type__company_type'] for item in queryset]
    data = [item['count'] for item in queryset]
    context = {
        'labels': labels,
        'data': data,
    }
    return render(request, 'index.html', context)

验证步骤

  1. 启动Django服务,访问页面打开浏览器开发者工具(F12),查看Console面板是否有JS报错。
  2. 查看页面源码,确认labels和data是否被正确渲染成数组格式(比如["医疗", "科技"]和[4, 6])。
  3. 确认Canvas元素存在且能被JS正确获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:12:43