如何对Django模型M2M字段注解并获取去重的关联实例列表
问题原因
你之前的写法逻辑错误核心在于:
- 先调用
values/values_list再执行annotate时,Django会按照values指定的字段分组,此时Count('devices')统计的是每个设备ID关联的Profile数量,和你要的「筛选出设备数达标Profile,再取这些Profile关联的所有设备」逻辑完全不符。 - 额外注意你描述的需求是「拥有1个及以上设备的Profile」,但代码里写的
dev_count__gt=1是大于1(即至少2个设备),如果需求确实是≥1,要改成dev_count__gte=1。
正确写法
方案1:基于你已有的profiles查询集直接反向查询
利用你定义的多对多反向关联名profiles,直接从Device表过滤关联了目标Profile的记录即可:
# 获取去重后的Device对象查询集 devices = Device.objects.filter(profiles__in=profiles).distinct() # 如果只需要设备ID的一维列表,加values_list即可 device_ids = Device.objects.filter(profiles__in=profiles).values_list('id', flat=True).distinct()
方案2:合并为单次查询(性能更优,自动转成子查询仅执行一次SQL)
不需要先单独查询Profile列表,直接在Device的查询中嵌入Profile的筛选条件:
devices = Device.objects.filter( profiles__in=Profile.objects.annotate( dev_count=Count('devices') ).filter(dev_count__gt=1) ).distinct()
内容的提问来源于stack exchange,提问作者everspader
相关产品推荐
相关产品推荐

