如何在Django ORM中合并无关联的Stock与Reserved查询集
问题描述
我正在编写一个Django视图,当前返回如下JSON结构:
[ { "field_id" : 1, "stock" : [ { "size" : "M", "total" : 3 } ], "reserved" : [ { "size" : "M", "total" : 1 } ] }, { "field_id" : 2, "stock" : [ { "size" : "M", "total" : 2 }, { "size" : "PP", "total" : 2 } ], "reserved" : [ { "size" : "PP", "total" : 1 }, { "size" : "M", "total" : 2 } ] } ]
为得到该结果,我使用了Django ORM的values和annotation:
reserved = Reserved.objects.all().values("size").annotate(total=Count("size")).order_by("total") stock = Stock.objects.filter(amount=0).values('size').annotate(total=Count('size')).order_by('total')
目前该实现没问题,但我希望将reserved查询集的数据整合到stock中,得到如下JSON结构:
[ { "field_id" : 1, "stock" : [ { "size" : "M", "total" : 3, "reserved": 1 } ], }, { "field_id" : 2, "stock" : [ { "size" : "M", "total" : 2, "reserved": 1 }, { "size" : "PP", "total" : 2, "reserved": 0 } ], } ]
注:Stock与Reserved模型之间无关联关系。请问是否可行?
解决方案
完全可行,核心思路是先把reserved数据转成便于快速查找的字典结构,再遍历stock数据补充对应的预留字段,具体步骤如下:
转换reserved数据为字典
将reserved查询集转为{size: total}的键值对格式,这样能以O(1)时间复杂度查找对应尺码的预留数量:reserved_dict = {item['size']: item['total'] for item in reserved}整合数据到stock条目
假设你的field_id来自Stock模型(若为其他分组逻辑,仅需调整分组依据即可),先按field_id分组查询stock数据,再遍历每个条目补充reserved字段:# 按field_id和size分组查询stock数据 stock_by_field = Stock.objects.filter(amount=0).values('field_id', 'size').annotate(total=Count('size')).order_by('field_id', 'size') # 按field_id分组整理最终数据 result = {} for item in stock_by_field: field_id = item['field_id'] size = item['size'] # 获取当前尺码的预留数量,无匹配则设为0 reserved_total = reserved_dict.get(size, 0) # 构建包含reserved字段的stock条目 stock_item = { 'size': size, 'total': item['total'], 'reserved': reserved_total } # 按field_id分组存储 if field_id not in result: result[field_id] = { 'field_id': field_id, 'stock': [] } result[field_id]['stock'].append(stock_item) # 转成最终的列表格式 final_data = list(result.values())返回JSON响应
在Django视图中直接返回处理后的final_data:from django.http import JsonResponse def your_view(request): # 执行上述数据处理逻辑 return JsonResponse(final_data, safe=False)
补充说明
- 该方案仅需两次数据库查询(stock和reserved各一次),后续均为内存操作,效率较高;
- 若
field_id不是来自Stock模型,只需调整分组的判断逻辑,核心的字典转换和字段补充逻辑保持不变。
内容的提问来源于stack exchange,提问作者Joey Fran
相关产品推荐
相关产品推荐

