Django模板传递request.path为URL参数时反向解析报错问题
报错原因
- 你配置的名为
page的路由,path参数的匹配规则为[^/]+,该正则仅能匹配不含斜杠/的连续字符。但你传入的request.path是类似/my_site/的字符串,本身包含斜杠,不符合路由匹配要求,因此反向解析失败。 - 即便调整正则允许斜杠,直接将完整路径作为URL路径参数传递,也很容易和其他同前缀路由产生匹配优先级冲突,稳定性差。
修改方案
优先推荐用查询参数传递来源路径,不需要改动现有路由,稳定性最高:
- 调整跳转链接写法,将来源路径编码后放到查询字符串中,避免特殊字符导致解析异常:
<a href="{% url 'page' %}?from={{ request.path|urlencode }}">Go to page</a>
- 在目标页视图中读取来源路径,增加安全校验避免开放重定向漏洞,再将路径传给模板:
def page_view(request): back_path = request.GET.get('from', '/') # 仅允许跳转到站内相对路径,拦截外链跳转 if not back_path.startswith('/') or back_path.startswith('//'): back_path = '/' return render(request, 'page.html', {'back_path': back_path})
*注意:必须加来源路径校验逻辑,拦截非站内路径跳转,避免被恶意构造参数触发开放重定向漏洞,把用户引导到钓鱼网站。
- 目标页的返回按钮直接使用传入的路径变量即可:
<a href="{{ back_path }}">返回</a>
如果你一定要把来源路径放在URL路径参数中传递,需要按如下方式调整路由(注意该路由必须放在所有notifications/前缀路由的最末尾,避免拦截其他正常路由):
- Django 2.0及以上版本,使用内置支持斜杠匹配的
path转换器:
# urls.py from django.urls import path from . import views urlpatterns = [ # 其他notifications前缀的路由放在前面 path('notifications/<path:path>', views.page_view, name='page'), ]
- 低版本Django使用
re_path修改正则规则,允许匹配斜杠:
# urls.py from django.urls import re_path from . import views urlpatterns = [ # 其他notifications前缀的路由放在前面 re_path(r'^notifications/(?P<path>.*)\Z$', views.page_view, name='page'), ]
调整后原模板的反向解析代码即可正常运行,但该方案路由维护成本高,不推荐使用。
内容的提问来源于stack exchange,提问作者vargaking
相关产品推荐
相关产品推荐

