Django合并两次查询:根据ModelB普通记录获取对应Base记录
Django 优化关联查询:合并两次查询为一次
针对你的需求,有两种更高效的方式替代原有的两次查询,下面分别说明:
方式一:使用子查询(仅一次数据库查询)
直接通过子查询获取目标记录对应的modela,再筛选出关联的base记录,整个过程只触发一次SQL查询,性能最优。
from django.db.models import Subquery, OuterRef # 获取对应base记录的ID base_record_id = ModelB.objects.filter( modela=Subquery(ModelB.objects.filter(id=modelb_pk).values('modela')), base=True ).values_list('id', flat=True).first()
方式二:使用Prefetch预取关联记录
如果需要同时获取目标普通记录和对应的base记录完整对象,适合用Prefetch来预取关联数据,整体是两次数据库查询(主查询+预取查询),但ORM层面是一次操作。
from django.db.models import Prefetch # 定义预取规则:筛选同modela下base为True的ModelB记录,存到自定义属性 base_prefetch = Prefetch( 'modela__modelb_set', # Django默认反向关联名:<模型小写>_set queryset=ModelB.objects.filter(base=True), to_attr='base_records' ) # 一次ORM操作获取目标记录及预取的base记录 target_record = ModelB.objects.filter(id=modelb_pk).prefetch_related(base_prefetch).first() # 提取对应的base记录(根据数据规则,这里只会有一条) base_record = target_record.modela.base_records[0] if target_record else None # 若仅需ID: base_record_id = base_record.id if base_record else None
说明
- 子查询方案:适合仅需获取base记录ID或单个字段的场景,数据库查询次数最少
- Prefetch方案:适合需要使用目标记录和base记录的多个字段的场景,代码可读性更好
内容的提问来源于stack exchange,提问作者Braiano
相关产品推荐
相关产品推荐

