Django 如何筛选满足多个指定外键关联章节条件的Story对象
最优实现方案
你可以使用annotate + Count的组合实现,比链式多次filter更简洁高效,且支持动态适配任意长度的标题列表:
首先导入依赖:
from django.db.models import Count
业务代码实现:
titles = ['Beginning', 'Middle', 'End'] target_length = 'Long' required_match_num = len(titles) stories_with_these_chapters = Story.objects.filter( chapters__title__in=titles, chapters__length=target_length ).annotate( # 如果业务中同一Story下不会有重复标题的章节,可以去掉distinct=True matched_num=Count('chapters', distinct=True) ).filter( matched_num=required_match_num )
方案优势
- 通用性强:无需修改代码就能适配任意长度的标题列表,不用手动写N层
filter链式调用 - 性能更高:底层SQL仅执行1次表JOIN,而链式N次
filter会执行N次JOIN,标题数量越多性能差距越明显 - 结果准确:和你原有写法返回结果完全一致,你的示例数据中只会返回ID为3的Story,符合预期。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

