Cory Schafer Django教程注册后redirect无需传参显示消息的疑问
Django redirect跨请求传递消息的实现原理
1. 先明确redirect和render的本质差异
render是服务端直接渲染指定模板,把当前请求的context数据传入模板生成HTML后返回给浏览器,属于单次请求的处理流程,所以你的自定义业务数据需要手动传入第三个context参数才能被模板读取。redirect不会渲染模板,它是给浏览器返回302/301重定向状态码,响应头携带目标路由地址,浏览器收到后会主动发起第二次全新的GET请求访问目标地址,两次请求完全独立,默认无法直接共享context数据。
2. 提示消息不是redirect传递的,是Django Messages框架实现的
你代码中调用的messages.success(request, f'Account created for {username}!')才是存储消息的核心逻辑,背后的实现机制如下:
- 调用messages系列方法时,Django会把这条消息存储到当前用户的会话(Session,默认存在服务端,和用户的身份Cookie绑定)中,标记为「待读取」状态。
- Django默认在模板上下文处理器中注册了messages处理器,你可以在
settings.py的TEMPLATES配置项的context_processors列表里看到django.contrib.messages.context_processors.messages,这个处理器会在每次渲染模板时自动把当前用户待读取的所有消息加入模板context,不需要你手动传参。 - 消息是「一次性」的:当模板读取并展示完这条消息后,Django会自动把它从Session中删除,刷新页面后就不会再重复显示。
3. 不用给redirect传参也能拿到消息的原因
消息存储在和用户身份绑定的Session里,第二次重定向后的GET请求会携带用户的身份Cookie,Django可以通过Cookie找到对应的Session,读取里面存储的未读消息,再通过上下文处理器自动注入模板,全程不需要你在redirect阶段手动传递数据。
内容的提问来源于stack exchange,提问作者Synectouche
相关产品推荐
相关产品推荐

