bigywater.tech
Django · 81

Django Messages Framework 的存储机制

messages.success(request, "保存成功") 之后,那条消息存在哪里?什么时候被删?消息很长怎么办?这篇看默认的 FallbackStorage,以及 Cookie / Session 两种存储的行为。

用完即删
读取后响应把 messages cookie 设成过期;没读之前跨请求一直保留
INFO
未设置 MESSAGE_LEVEL 时最低保存 INFO,debug() 被忽略
2 KB
cookie 放不下时(2 条 × 3000 字符随机内容)FallbackStorage 转存 session

默认存储

实测 · 本机执行输出
添加 2 条(短消息): {'Set-Cookie messages': True, 'session 行数': 0}  messages cookie 长度 = 144
下一个请求读取: {'msgs': [['info', 'm0 d9d811591'], ['info', 'm1 521abd77d']]}  读取后 cookie 被删除(Set-Cookie 过期): Thu, 01 Jan 1970 00:00:00 GMT
再读一次: {'msgs': []}

消息框架适合「重定向后提示一次」。数据先在 cookie 里,所以短消息不需要 session、也没有数据库开销。

级别

实测 · 本机执行输出
{'msgs': [['info', 'inf'], ['success', 'ok'], ['warning', 'warn'], ['error', 'err']]}
settings 里有没有 MESSAGE_LEVEL: False ; 常量 INFO = 20 , DEBUG = 10 (未设置时最低级别是 INFO,所以 debug() 没有保存)

用 MESSAGE_LEVEL 调整最低级别,比如开发时设成 DEBUG 才能看到调试消息。

什么算「用过」

实测 · 本机执行输出
/peek/ 只取 len() 与类型: {'storage': 'FallbackStorage', 'len': 1}
之后 /show/ 还能读到: {'msgs': [['info', 'm0 a49c0742b']]}
中间发了一个没读消息的请求 /noop/,再 /show/: {'msgs': [['info', 'm0 7efbe39b0']]} (消息没读之前一直保留)

模板里 {% for m in messages %} 遍历就是「用过」。所以如果一个页面没有遍历消息(比如 API 视图),消息会一直留到下一个会遍历的页面。

放不下时

实测 · 本机执行输出
1 条 × 50 字符:messages cookie 长度   163  session 行数 0  读取到 1 条
5 条 × 300 字符:messages cookie 长度  1274  session 行数 0  读取到 5 条
2 条 × 3000 字符:messages cookie 长度    87  session 行数 1  读取到 2 条

注意:我第一次用重复字符 x*3000 测,cookie 里的内容被压缩后很小,看不到溢出——测存储上限要用随机内容。

三种存储

实测 · 本机执行输出
  [CookieStorage] Set-Cookie messages: True | session 行数: 0 | 读取: {'msgs': [['info', 'm0 507702c52']]}
  [SessionStorage] Set-Cookie messages: False | session 行数: 1 | 读取: {'msgs': [['info', 'm0 8065b1baf']]}
  [FallbackStorage] Set-Cookie messages: True | session 行数: 0 | 读取: {'msgs': [['info', 'm0 9b774d268']]}

选择:不想用 session(无状态)选 CookieStorage,消息内容注意不要放敏感信息(cookie 里可读,签名只防篡改);要可靠就用 SessionStorage。

分步演示:消息的一生

消息框架
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。django.test.Client;cookie 长度取自响应的 Set-Cookie
    • 没有验证:CookieStorage 超限时的丢弃行为、消息 tags 与 extra_tags 的渲染、异步视图里的消息、消息中 HTML 的转义(第 84 篇)
    京ICP备2026067502号-1京公网安备11010502063487号