Django如何高效单次查询关联指定branch的ProductStorage并按Storage分组
Django 一次查询实现按Storage分组展示关联的ProductStorage
完全可以通过一次查询+内存分组实现高效需求,避免二次查询带来的性能损耗。
核心思路
利用Django的select_related预取关联的Storage对象,一次性拉取所有需要的数据,再在Python内存中完成分组操作——这是Django中处理这类关联分组最常用的高效方案。
代码实现
假设你的ProductStorage模型定义了product(关联Product)和storage(关联Storage)两个外键字段,具体代码如下:
# 目标分支值,替换成你要查询的特定branch target_branch = "华东区" # 一次查询获取所有符合条件的ProductStorage,同时预取关联的Storage和Product(如果需要Product数据的话) product_storages = ProductStorage.objects.select_related('storage', 'product').filter(storage__branch=target_branch).order_by('storage__id') # 在内存中按Storage的name和color分组 grouped_result = {} for ps in product_storages: # 生成分组键,对应你示例中的"Storage.Name1, Storage.Color1"格式 group_key = f"{ps.storage.name}, {ps.storage.color}" # 将当前ProductStorage的属性加入对应分组 if group_key not in grouped_result: grouped_result[group_key] = [] grouped_result[group_key].append({ "product_name": ps.product.name, "ps_attr1": ps.attr1, # 替换成你的ProductStorage实际额外属性 "ps_attr2": ps.attr2 })
为什么这是最优方案
- 避免N+1查询:
select_related会把ProductStorage、Storage甚至Product的数据通过一次SQL JOIN查询全部拉取,不会出现每个ProductStorage单独查一次Storage的低效情况。 - 内存分组高效:Python层面的分组操作是基于已获取的数据集进行的内存遍历,比多次数据库查询快得多。
- 逻辑清晰:代码结构简单,符合Django ORM的最佳实践,后续维护成本低。
最终效果
grouped_result的结构完全匹配你给出的示例:
"Storage.Name1, Storage.Color1": [ {"product_name": "Product1", "ps_attr1": "xxx", ...}, {"product_name": "Product2", "ps_attr1": "yyy", ...}, ... ], "Storage.Name2, Storage.Color2": [ {"product_name": "Product3", "ps_attr1": "zzz", ...}, ... ]
内容的提问来源于stack exchange,提问作者progNewbie
相关产品推荐
相关产品推荐

