cached_template未生效主因是配置错误或中间件干扰:需正确嵌套cached.Loader包裹原始loader,而非并列;其缓存基于路径与文件修改时间,重启开发服务器才能清除内存中缓存。

为什么 cached_template 没生效?检查中间件顺序
默认情况下,Django 的模板缓存机制依赖 django.template.loaders.cached.Loader,但它不会自动生效——你得手动配置,且必须确保 CommonMiddleware 或其他涉及响应缓存的中间件不干扰它。最常见的情况是:你加了 cached.Loader,但页面每次刷新仍走文件系统读取。
- 确认
TEMPLATES配置中,BACKEND是django.template.backends.django.DjangoTemplates,且OPTIONS['loaders']用的是cached.Loader包裹原始 loader,例如:['django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ]] - 不要把
cached.Loader和filesystem.Loader并列放在同一层 list 里,否则它只缓存第一个 loader 的结果 -
cached.Loader不影响模板继承链的解析逻辑,但会缓存编译后的Template对象——所以首次加载仍慢,后续才快
缓存键怎么算?模板路径变更后旧缓存不更新
cached.Loader 的缓存键基于模板路径字符串(如 'blog/post_detail.html')和文件修改时间戳(os.stat().st_mtime)。这意味着:只要文件没改,哪怕你清空了 django.core.cache 后端,它仍可能从内存里返回旧模板对象。
- 开发时改了模板但没看到效果?不是缓存后端问题,而是
cached.Loader内部用lru_cache或模块级 dict 存的编译结果,重启 dev server 才能清掉 - 生产环境用
memcached或redis做模板缓存后端时,cached.Loader本身并不使用那个 cache,它只用 Python 进程内内存——所以别指望通过cache.delete_pattern('template.*')清掉它 - 如果你用符号链接部署、或挂载 NFS 共享模板目录,
st_mtime可能不准,导致缓存永不刷新
什么情况下不该用 cached.Loader?
它不是银弹。对小项目或低并发场景,启用它反而增加首字节延迟;对动态生成模板名的场景(比如 get_template(f'emails/{lang}/welcome.html')),如果 lang 组合爆炸,缓存条目会快速膨胀,且无法预热。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 模板数量少于 50 个、QPS cached.Loader 带来的收益几乎不可测
- 用了
select_template()且候选列表很长(比如按设备类型 + 语言 + 主题三重 fallback),缓存命中率会急剧下降 - 自定义 loader(如从数据库读模板)没实现
get_template_sources()或没正确返回mtime,cached.Loader会退化为每次都重新编译
DEBUG=True 下 cached.Loader 自动禁用
这是最容易被忽略的一点:Django 在 DEBUG=True 时,无论你怎么配 cached.Loader,它内部都会跳过缓存逻辑,直接调用子 loader。所以本地开发永远看不到“缓存生效”的现象,不是配置错,是设计如此。
立即学习“Python免费学习笔记(深入)”;
- 验证是否真起作用,必须在
DEBUG=False下测试,且确保ALLOWED_HOSTS已设置(否则 500 错误会掩盖真实问题) - 线上环境若仍没提速,用
django.template.loader.find_template手动调一次,再看django.template.loaders.cached.Loader.get_template_sources是否被调用多次——可以加个简单 log 确认 - 注意
cached.Loader不缓存{% include %}的子模板查找过程,只缓存顶层get_template()调用;嵌套太深时,瓶颈可能根本不在这里

















