Django中redirect传递context触发NoReverseMatch异常如何解决
问题根因
NoReverseMatch报错是因为你对reverse()的用法理解错了:reverse()的作用是根据urls.py里定义的路由规则反向生成URL,传入的kwargs必须和目标路由定义的路径参数一一对应。你直接把业务数据my_data作为data参数传给kwargs,但td:success对应的路由里根本没有定义名为data的路径占位符,自然匹配不到对应路由规则,直接抛错。
另外要明确两个方法的本质区别:
render是服务端直接把上下文数据注入模板、生成完整HTML返回给客户端,全程只有一次请求,当然可以自由传递上下文redirect是返回302响应,告诉浏览器去请求新的URL地址,会产生一次全新的GET请求,新请求默认不会携带上一次请求里的自定义上下文数据,自然也不能像render一样直接传模板上下文。
可落地的解决方法
根据你要传递的数据类型、体量选择对应方案即可:
- 传递操作状态、提示文案这类一次性小数据:用Django自带的messages框架
- 确认项目配置默认开启(新建Django项目默认已经在
INSTALLED_APPS和中间件里配置好了messages相关项) - 跳转前存入数据:
from django.contrib import messages # 你的业务逻辑处理 messages.info(request, '操作完成', extra_data=my_data) return redirect('td:success') - 在success页面对应的模板/视图中直接读取messages内容即可,数据存在session中,读取一次后自动清除,非常适合跳转提示场景。
- 确认项目配置默认开启(新建Django项目默认已经在
- 传递简单类型的非敏感小数据(比如数字ID、短字符串):拼URL查询参数
不要把这类参数塞给reverse()的kwargs,直接拼接在生成的URL后面:
跳转到success视图后,通过from django.urls import reverse from urllib.parse import urlencode redirect_url = reverse('td:success') # 注意my_data必须是字符串、数字这类可序列化的简单类型,不能传复杂对象 query_params = urlencode({'data_id': my_data}) return redirect(f'{redirect_url}?{query_params}')request.GET.get('data_id')就能拿到传入的值。 - 传递复杂结构、大体量数据:临时存在session中
复杂数据不要塞URL,直接存在当前用户的会话里:
在success视图里取完数据记得删除,避免数据残留:# 发起跳转的视图 request.session['temp_biz_data'] = my_data return redirect('td:success')# success页面对应的视图 def success(request): biz_data = request.session.pop('temp_biz_data', None) # 后续渲染逻辑 - 如果你本来就打算把数据作为URL路径的一部分:先补全路由定义
如果业务设计就是要让数据出现在URL路径里,先在urls.py里给success路由加上对应参数占位符:
注意:路径参数会直接暴露在URL中,仅适合传递非敏感的简单类型标识数据,不要传敏感信息、大文本或者复杂对象# app内的urls.py path('success/<int:data_id>/', success_view, name='success')
内容的提问来源于stack exchange,提问作者Ebrima Sise
相关产品推荐
相关产品推荐

