直接用 django-redis 配 redis + django 原生缓存 api 即可实现分布式缓存,但需严格配置 backend、location、client_class 等项,否则静默降级为 locmemcache 导致 cache.get() 总返回 none;模板 {% cache %} 键由参数拼接生成,不可哈希对象会报错,失效需主动清理且注意 key_prefix;session 存 redis 必须正确配置 session_engine 与 session_cache_alias,不可混用旧版 redis 引擎。

直接用 django-redis 配 Redis + Django 原生缓存 API 就能跑通分布式缓存,不需要自己封装连接池或序列化逻辑;但只要漏掉 CLIENT_CLASS 或写错 BACKEND,cache.get() 就会静默返回 None,根本没连上 Redis。
确认 CACHES 配置是否真正接入 Redis
Django 不会报错提示“Redis 连不上”,而是自动降级到 LocMemCache,导致所有 cache.set() 看似成功、cache.get() 却总为 None。必须逐项核对:
-
BACKEND必须是"django_redis.cache.RedisCache",不是"django.core.cache.backends.redis.RedisCache"(后者是 Django 5.0+ 原生支持,当前主流版本缺压缩、连接池等关键能力) -
LOCATION推荐用 URL 格式:"redis://127.0.0.1:6379/1";避免用localhost,Docker 或云环境 DNS 解析可能卡住 -
OPTIONS中必须包含"CLIENT_CLASS": "django_redis.client.DefaultClient",否则setex等方法缺失,序列化失败 - 如果 Redis 开密码,URL 必须带格式:
"redis://:mypass@127.0.0.1:6379/1"
验证方式:进 python manage.py shell,执行 from django.core.cache import cache; cache.set('test', 'ok', 30); print(cache.get('test'))。输出 None?立刻检查 cache.client.connection_pool.get_connection() 是否抛异常。
模板 {% cache %} 标签的键生成规则和陷阱
模板缓存不是“存 HTML 字符串”那么简单,它的键由所有传入参数拼接生成,任意一个变化都会触发新缓存 —— 且不可哈希的对象会直接报错:
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 参数如
{% cache 300 sidebar user.id request.path %},键类似cache_sidebar_1_/products/;user.id是整数,request.path是字符串,Django 原样拼接,不 JSON 序列化 - 不能传
None、datetime、request整体 —— 它们不可哈希,会抛TypeError: unhashable type;改用request.user.id、request.GET.get("q")等具体字段 - 前端注入的
csrf_token或动态时间戳会让每次请求键都不同,缓存形同虚设;建议在 Nginx 层 strip 掉无关 query 参数,或用KEY_PREFIX统一前缀便于清理
缓存失效必须主动清理,Django 不自动感知数据变更
模板缓存键名由 Django 自动生成且不暴露,你无法靠猜去删。常见误操作是“改了数据库却忘了清缓存”,页面一直显示旧内容:
- 推荐在视图或信号中,用**完全一致的参数组合**调用
cache.delete_pattern("cache_sidebar_*")(需确保django_redis.cache.RedisCache启用了 pattern 支持) - 更稳妥做法:给缓存加可预测前缀,例如
{% cache 300 "product_sidebar" product.id %},失效时删cache_product_sidebar_123 - 如果用了
KEY_PREFIX = "myapp",实际键是"myapp:cache_sidebar_1_/home",清理时必须带上前缀
别混淆 cache 和 session 的 Redis 配置
把 Session 存 Redis 不只是改 SESSION_ENGINE,否则用户频繁登出或状态丢失 —— 缓存和 session 的生命周期、连接池、序列化方式完全不同:
- Session 要用
SESSION_ENGINE = "django.contrib.sessions.backends.cache"+SESSION_CACHE_ALIAS = "default",且CACHES["default"]必须已正确配置为 Redis - 不能只配
SESSION_ENGINE = "django.contrib.sessions.backends.redis"(这是旧版第三方包写法,与django-redis冲突) - Session 数据默认不压缩,若启用了
COMPRESSOR,需确认 session serializer 兼容性(推荐保持默认PickleSerializer)
最易被忽略的是:缓存键的生成逻辑藏在模板编译期,你改了参数顺序或类型,键就变了,但错误现象是“缓存不生效”,而不是报错 —— 得从 cache.get_many() 或 Redis CLI 直接查键名才能定位。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










