如何在Django ORM中实现多次反向外键查询(获取指定商店集合的关联寄售记录)
如何在Django ORM中实现多次反向外键查询(获取指定商店集合的关联寄售记录)
嘿,我来帮你搞定这个问题!你想要通过target_stores这个商店集合直接拿到对应的所有寄售记录,但你当前写的target_stores.consignments.all()肯定会报错——因为你的模型里Store和Consignment之间没有直接的关联,中间隔了Stock和Order两层关系呢。
别担心,我们可以通过Django ORM的跨表双下划线查询来实现这个需求,下面给你两种靠谱的写法:
方法一:直接从Consignment出发反向筛选(推荐)
这是最简洁高效的方式,直接从Consignment模型入手,通过双下划线穿透关联的表,筛选出对应商店集合的记录:
target_stores = Store.objects.filter(name__startswith="One") # 核心:通过order__stock__store__in穿透三层关联,找到对应商店的寄售 consignments = Consignment.objects.filter(order__stock__store__in=target_stores)
原理很简单:Consignment关联Order,Order关联Stock,Stock关联Store,我们用__来逐层访问关联字段,__in用来匹配target_stores这个集合里的所有商店。
方法二:先拿关联订单再取寄售(可选)
如果你想分步处理,也可以先拿到所有关联的订单,再从中提取对应的寄售记录:
target_stores = Store.objects.filter(name__startswith="One") # 先找到所有属于目标商店的订单 related_orders = Order.objects.filter(stock__store__in=target_stores) # 再通过订单的consignment外键筛选寄售 consignments = Consignment.objects.filter(id__in=related_orders.values('consignment_id'))
这种写法逻辑更直观,但本质和方法一类似,性能上差异不大,看你个人习惯选择就行。
另外提醒一下:你原来的写法target_stores.consignments.all()之所以不行,是因为Store模型本身没有consignments这个反向关联属性——只有当模型之间有直接外键/多对多关联时,才会自动生成这样的反向属性,而这里隔了两层,所以得用跨表查询来穿透。
备注:内容来源于stack exchange,提问作者Ahmed Ashraf
相关产品推荐
相关产品推荐

