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

在Django中使用Chart.js实现当年月度发票统计折线图

Django动态获取月度发票数据生成Chart.js折线图

需求说明

需要在Django中结合Chart.js创建折线图,展示当年各月份的发票数量,数据需从名为invoice的模型的Invoice_date(DateField类型)字段动态获取。当前views.py中的数据为硬编码,需修改为动态获取。

原views.py代码

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from .models import invoice  # 确保导入对应模型
import json

def home(request):
    if request.user.is_authenticated:
        customers = User.objects.filter(groups__name='Customer').count()
        totalinvoice = invoice.objects.all().count()
        supplier = User.objects.filter(is_staff=True).count()

        # chart
        labels = ["Jan","Feb","Mar","Apr","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]  # 原代码遗漏了May
        data = [12,14,19,25,28,80,23,35,46,78,45,23] # 此处需动态获取数据

        return render(request, 'home.html', {
            'totalinvoices':totalinvoice,
            'customers':customers,
            'supplier':supplier,
            "labels":json.dumps(labels),
            "data":json.dumps(data),
        })
    else:
        return redirect("login")

动态获取数据的实现方案

利用Django ORM的聚合功能,结合ExtractMonth和Count统计当年各月发票数量,同时补全无发票月份的0值,保证数据覆盖1-12月。

修改后的views.py代码

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from .models import invoice
from django.db.models import Count
from django.db.models.functions import ExtractMonth
from django.utils import timezone
import json

def home(request):
    if request.user.is_authenticated:
        customers = User.objects.filter(groups__name='Customer').count()
        totalinvoice = invoice.objects.all().count()
        supplier = User.objects.filter(is_staff=True).count()

        # 获取当前年份
        current_year = timezone.now().year

        # 统计当年各月的发票数量
        monthly_invoices = invoice.objects.filter(
            Invoice_date__year=current_year
        ).annotate(
            month=ExtractMonth('Invoice_date')
        ).values('month').annotate(
            count=Count('id')
        ).order_by('month')

        # 初始化1-12月数据为0,避免缺失月份导致折线图断层
        monthly_data = {month: 0 for month in range(1, 13)}
        # 将统计结果填充到对应月份
        for item in monthly_invoices:
            monthly_data[item['month']] = item['count']

        # 按月份顺序提取数据,与labels顺序匹配
        labels = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
        data = [monthly_data[month] for month in range(1, 13)]

        return render(request, 'home.html', {
            'totalinvoices':totalinvoice,
            'customers':customers,
            'supplier':supplier,
            "labels":json.dumps(labels),
            "data":json.dumps(data),
        })
    else:
        return redirect("login")

关键细节说明

  • 年份过滤:通过Invoice_date__year=current_year精准筛选当前年份的发票记录。
  • 月度统计:用ExtractMonth提取发票日期的月份字段,再通过Count('id')统计对应月份的发票总数。
  • 补全缺失月份:初始化包含1-12月的字典,默认值设为0,确保即使某月份无发票,折线图也能正常显示该月数据。
  • 顺序匹配:按1到12月的顺序提取数据,保证与labels中的月份顺序完全对应。

内容的提问来源于stack exchange,提问作者TS Tamarai Selvan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:25:23