如何使用更优的Django ORM方法查询指定放映场次的可用座位
最优Django ORM实现方案
你原来的写法需要把所有预订座位ID加载到Python内存,数据量大时性能损耗很高,以下两种写法都不需要生成中间ID列表,所有逻辑直接在数据库层面执行,仅需一次查询即可得到结果,性能远优于原有实现:
写法1:反向跨表过滤(最简洁)
利用Django ORM的反向外键关联特性,直接过滤关联的预订记录,写法极简:
# spk为指定放映场次的主键 target_show = Show.objects.get(pk=spk) available_seats = Seat.objects.filter( hall=target_show.hall ).exclude( booking__show=target_show )
该写法会自动生成左连接查询,逻辑和你给出的原生SQL完全一致。
写法2:Exists子查询(性能最优,适合大数据量场景)
用Exists子查询判断座位是否已被预订,查询效率更高:
from django.db.models import Exists, OuterRef target_show = Show.objects.get(pk=spk) has_booked = Booking.objects.filter( show=target_show, seat=OuterRef('pk') ) available_seats = Seat.objects.filter( hall=target_show.hall ).filter( ~Exists(has_booked) )
内容的提问来源于stack exchange,提问作者akash deep
相关产品推荐
相关产品推荐

