Django如何通过多个关联模型的ManyToManyField获取可迭代QuerySet
最优实现方案
直接通过Django ORM跨表查询即可,仅需1次数据库查询,直接返回去重后的可迭代Doctor查询集:
# 写法1:直接通过城市名查询 doctor_qs = Doctor.objects.filter(clinic__city__name="Kabul").distinct() # 写法2:如果已经提前获取了城市对象,推荐用这个,少一次City表查询 my_city = City.objects.get(name='Kabul') doctor_qs = Doctor.objects.filter(clinic__city=my_city).distinct()
方案说明
- 核心使用Django ORM的双下划线
__跨表查询语法:clinic__city是从Doctor表反向关联到多对多关联的Clinic表,再关联到Clinic的外键City表,直接筛选出关联诊所属于目标城市的医生 distinct()直接在数据库层面完成去重,替代原有在Python层面对列表转set的操作,性能提升显著- 返回结果是原生
QuerySet对象,支持链式调用后续过滤、分页、排序等操作,完全满足可迭代需求
原有方案的性能问题
原有实现属于典型的N+1查询问题:
- 第一次查询拿到目标城市的所有诊所,产生1次查询
- 循环遍历每个诊所时,单独查询该诊所关联的医生,有多少个诊所就会多产生多少次查询
- 最后需要在Python层面对大量返回数据做去重,数据量越大内存和时间开销越高
内容的提问来源于stack exchange,提问作者Arif Haidari
相关产品推荐
相关产品推荐

