想给前端提供这样一个图表数据的接口:
本来以为很简单,但实现后发现数据不对:
如果没有数据的季度,数据库是没有记录的,比如:
1、3季度有数据,2季度没有数据,但实际展示的时候第三季度的数据跑到第二季度去了,造成数据位置错乱。
后面翻了网上很多资料,都没达到我想要的效果(小白可能还没理解透,所以没有办法按网上大神写的方法实现。),最后自己研究了2天,解决这个问题,特在此记录和分享一下。
1、解决思路
因为需求是按季度统计,这样一年的数据记录就比较少,就4条记录,
所以我先模拟4条为0的数据,
然后用查询出来的数据与模拟数据合并,
这样就实现有数据的季度就更新数据,没有数据的季度就为0了。
下面直接贴代码:
2、代码
# 手动创建季度列表;
m_quarter = ['第1季度', '第2季度', '第3季度', '第4季度']
# 模拟一组为0的数据,与分组查询比对。数据格式保持和分组查询一致。
quarter_list = [
{'quarter': 1, 'count': Decimal('0.00')},
{'quarter': 2, 'count': Decimal('0.00')},
{'quarter': 3, 'count': Decimal('0.00')},
{'quarter': 4, 'count': Decimal('0.00')}
]
# 一、2022年【合同额】数据统计
# 1、获取2022年所有合同数据
year_contract =contractModel.objects.filter(sign_date__year=2022).values('sign_date','contract_quota')
# 2、按季度分组求'contract_quota'的和
contract_res = list(year_contract.annotate(quarter=ExtractQuarter('sign_date'))
.values('quarter').order_by('quarter').annotate(count=Sum("contract_quota")))
# 3、数据比对处理
contract_data = contract_res + quarter_list # 与空数据比对合并成新的list
# 4、去重合并后的数据
new_list = [] # 存储去重后的list。
values = [] # 用于存储当前已有的值
for i in contract_data:
if i['quarter'] not in values:
new_list.append(i)
values.append(i['quarter'])
# 5、按指定key 排序。(这里因为'quarter'的值是1-4,所以用它排序正合适)
new_contratct_data = sorted(new_list, key=lambda e:e.__getitem__('quarter'))
# 6、封装接口需要的数据格式
contract_list = []
for i in new_contratct_data:
contract_list.append(float(i["count"]))
# end
all_list = {
'm_quarter': m_quarter, # 季度
'contract_list': contract_list, #合同数据
'money_list': money_list,
'subcontract_list': subcontract_list,
'pay_list': pay_list
}
data = pd.DataFrame.from_dict(data=all_list, orient='index').fillna(value=0.0)
# print(data)
return Response(data=data)
3、返回数据结果
{
"0": [
"第1季度",
380.0,
0.0,
300.0,
0.0
],
"1": [
"第2季度",
60.0,
180.0,
0.0,
0.0
],
"2": [
"第3季度",
203.0,
0.0,
0.0,
138.0
],
"3": [
"第4季度",
0.0,
21.0,
400.0,
0.0
]
}
4、最终效果
这样最终达到了自己想要的效果,没有记录的季度或者数据统统统统为“0”占位。