You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django使用filter()时是否缓存关联表?示例场景疑问

Django Filter与关联表缓存的疑问解答

嘿,这问题问到点子上了,刚好是Django ORM里容易踩的N+1查询坑点,我给你掰扯清楚:

1. Django使用filter()时,会缓存关联表吗?

答案是不会,得拆成两点理解:

  • 首先,filter()本身只是构建一个查询集(QuerySet),这时候根本没触发数据库查询,更别说缓存关联表了。只有当你实际遍历查询集、调用len()或者取具体元素(比如e[0])时,才会执行SQL语句。
  • 其次,就算执行了查询,默认情况下Django ORM只会拉取主表(比如这里的Entries)的数据,不会主动把关联表(Blog)的内容同步缓存下来。如果之后你再访问每个Entry对象的blog属性,Django会单独给每个Entry发一次查询去取对应的Blog数据——这就是烦人的N+1查询问题。

2. 示例场景:e = Entries.objects.filter(blog__name='Something')的情况

这个语句里,blog__name='Something'只是用来筛选Entries的条件,Django会生成带JOIN的SQL来找出符合要求的Entry,但不会把Blog表的字段数据返回并缓存。具体来说:

  • 如果你只需要Entry本身的数据,完全不用访问关联的Blog,那加不加select_related都没影响;
  • 但如果你之后要用到每个Entry的blog属性(比如e[0].blog.name),那必须加上select_related('blog')!这样Django会一次性把Entry和对应的Blog数据都查询出来,避免后续的N次额外数据库请求。

举个直观对比:

  • 不加预加载:执行e = Entries.objects.filter(blog__name='Something')后,第一次查询拿到所有符合条件的Entry;当你遍历e并访问每个item的blog时,每访问一次就会发一次新查询。
  • 加预加载:e = Entries.objects.select_related('blog').filter(blog__name='Something'),这时候只会发一次SQL查询,把Entry和关联的Blog数据都取回来,之后访问item.blog直接用缓存的数据,不会再碰数据库。

内容的提问来源于stack exchange,提问作者Utumbu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:11:44