如何基于状态统计表格数据,计算仓库打印机纸张余量?
正确实现打印机纸张余量统计的方案
原代码存在的问题
- 模型中未定义
dateaction字段,但视图里使用该字段排序,会触发字段不存在的错误 get_queryset里错误用annotate+Sum给单条记录计算总和,不符合全局余量统计的需求get_context_data方法缩进错误,被嵌套在get_queryset内部,无法被正常调用
修正后的代码实现
1. 模型修正(补全缺失字段,按需选择)
# models.py from django.db import models from django.urls import reverse class PaperReport(models.Model): name = models.CharField('Office', max_length=255) amount = models.IntegerField('Number') status = models.CharField('Status', max_length=255) # 若需要按操作时间排序,添加该日期字段;不需要则可删除 dateaction = models.DateTimeField('Action Date', auto_now_add=True) def get_absolute_url(self): return reverse('paper_list')
2. 视图逻辑修正
# views.py from django.views.generic import ListView from django.db.models import Sum, Case, When, F, IntegerField from .models import PaperReport class PaperReportView(ListView): model = PaperReport template_name = 'paper_list.html' # 模型添加dateaction后保留该排序,否则删除或替换为其他字段 ordering = ['-dateaction'] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 直接聚合计算全局余量:Arrived状态加对应数量,Given状态减对应数量 total_left = PaperReport.objects.aggregate( total=Sum( Case( When(status='Arrived', then=F('amount')), When(status='Given', then=-F('amount')), default=0, output_field=IntegerField(), ) ) )['total'] # 处理空数据场景,避免页面显示None context['paper_left_sum'] = total_left if total_left is not None else 0 return context
3. 模板保持不变
<!-- paper_list.html --> <h2>Printer paper left: {{ paper_left_sum }}</h2> <div> {% for case in object_list %} <div> <p>{{ case.amount }} pcs {{ case.status}} for {{ case.name }}</p> </div> {% endfor %} </div>
关键修正说明
- 移除错误的单条记录标注逻辑,直接对全表数据做聚合统计,这是全局余量的正确计算方式
- 修复
get_context_data的缩进问题,确保它作为类方法被正常调用 - 增加空数据处理:当无任何记录时,将统计结果转为0,避免页面显示异常
内容的提问来源于stack exchange,提问作者Toshik
相关产品推荐
相关产品推荐

