Django无需指定具体size值查询同size的terrain模型对应location的方法
实现方案
你可以不用提前指定具体的size取值,通过Django ORM的分组、聚合功能就能直接完成需求:
方案1:使用ArrayAgg一步到位(推荐,Django 3.2+ 支持)
该方案仅需一次数据库查询,就能直接返回每个size对应的所有location列表:
from django.db.models import ArrayAgg # 按size字段分组,同分组的location会被聚合为列表 size_location_map = terrain.objects.values("size").annotate( same_size_locations = ArrayAgg("location", distinct=True) )
返回结果的遍历方式如下:
for item in size_location_map: current_size = item["size"] location_list = item["same_size_locations"] # 此处可处理对应size下的所有location
注:如果只需要存在至少2个同size记录的分组,可以在查询后追加
filter(count__gte=2),同时要在annotate里新增统计数量的逻辑:from django.db.models import ArrayAgg, Count size_location_map = terrain.objects.values("size").annotate( count = Count("id"), same_size_locations = ArrayAgg("location", distinct=True) ).filter(count__gte=2)
方案2:兼容低版本Django/所有数据库的实现
如果你的Django版本低于3.2,或者使用的数据库不支持ArrayAgg(比如低版本SQLite),可以先拉取所有去重的size,再逐个查询对应location:
# 先拿到所有去重后的size值 all_unique_sizes = terrain.objects.values_list("size", flat=True).distinct() result = {} for size in all_unique_sizes: result[size] = list(terrain.objects.filter(size=size).values_list("location", flat=True))
该方案逻辑简单无版本依赖,缺点是会产生N+1次数据库查询(N为不同size的数量),数据量不大的场景下可以放心使用。
内容的提问来源于stack exchange,提问作者med mansouri
相关产品推荐
相关产品推荐

