Django中select_related与prefetch_related对比及树形表多级父级预取实现
解决方案:预取两级父级分类
嘿,这个问题我太熟悉了!要实现预取查询结果中每个分类的两级父级、避免迭代时产生额外数据库查询的需求,直接用Django ORM的select_related()方法就能搞定,而且正好对应你想要的两次自表LEFT JOIN操作。
核心代码实现
因为你的parent字段是ForeignKey(一对一/多对一类型的关联),select_related()就是专门用来处理这类关联的——它会通过SQL JOIN语句,把关联对象的数据一次性拉取回来,彻底解决N+1查询问题。
要预取两级父级,只需要在查询时链式指定关联路径即可:
categories = Category.objects.filter(name__contains=something).select_related('parent__parent')
为什么这么做?
执行这条查询时,Django会自动生成包含两次LEFT JOIN的SQL语句:
- 第一次JOIN当前分类表和父级分类表(关联
parent字段) - 第二次JOIN父级分类表和祖父级分类表(关联父级的
parent字段)
这样所有需要的数据都会在一次数据库请求中被获取,之后你迭代categories的时候,直接访问category.parent或者category.parent.parent都不会触发新的查询,完全符合你的需求。
扩展小技巧
如果之后需要预取更多层级的父级(比如三级),只需要继续扩展关联路径就行,比如:
# 预取三级父级 categories = Category.objects.filter(name__contains=something).select_related('parent__parent__parent')
内容的提问来源于stack exchange,提问作者user3599803
相关产品推荐
相关产品推荐

