Django 模板中获取 URL:request.path 与 path_info、get_full_path、build_absolute_uri 的区别
在 Django 模板中,经常需要获取当前 URL。
\n- \n
- 导航栏“当前菜单激活” \n
- 登录后“返回原来页面(next)” \n
- 生成 canonical URL / 分享链接 \n
- 包含查询字符串的“当前页面不变”链接 \n
然而,除了 {{ request.path }},还有许多类似的属性,容易混淆。今天我们将清晰比较下面四个常用属性。
- \n
request.path\nrequest.path_info\nrequest.get_full_path()\nrequest.build_absolute_uri()\n
\n
{{ request }} 是从哪里来的
\n在模板中看到 {{ request }},通常意味着 request context processor 已开启。
- \n
django.template.context_processors.request负责将request放入模板上下文。 \n- 该 context processor 在
TEMPLATES设置的OPTIONS[\'context_processors\']中注册后生效。 \n
换句话说,Django 默认在 settings.TEMPLATES 中将 request 设为全局上下文,除非开发者刻意移除,否则用户可以无障碍使用。
request 对象本身是 Django 在接收请求时创建的 HttpRequest(实际上是 WSGI/ASGI 请求子类),并将其传递给视图。该对象包含 path、path_info 等属性。

\n
一句话总结:四个属性的记忆方式
\n- \n
path:去掉域名/协议,只保留路径 \npath_info:应用看到的真实路径(去掉脚本前缀) \nget_full_path():path+ 查询字符串 \nbuild_absolute_uri():完整的 URL(协议+域名+路径) \n
现在我们逐一深入。
\n\n
1) request.path:无域名的“路径(path)”
\nrequest.path 只返回 不含域名/协议 的请求路径。例如:
- \n
/music/bands/the_beatles/\n
何时有用
\n- \n
- 简单比较,例如菜单激活 \n
django\n {% if request.path == "/settings/" %}active{% endif %}\n* 判断“此页面属于哪个分类”,如前缀比较
django\n {% if request.path|slice:":5" == "/api/" %}...{% endif %}
\n
2) request.path_info:在部署环境中更稳的“真实路径”
\nDjango 文档的核心要点是:
\n- \n
- 某些服务器配置会将 URL 路径拆分为 脚本前缀(SCRIPT_NAME) 与 path info。 \n
path_info始终包含 path info 部分(即不受环境影响)。 \n
简而言之,在应用挂载在 /app 等前缀下(反向代理、子路径部署等)时,path 与 path_info 可能不同。
何时有用
\n- \n
- 需要考虑子路径部署(如
/app/)时,想用“应用基准路径”判断 \n - 测试/生产服务器前缀可能不同 \n
\n\n通常在单域名根路径(
\n/)下运行时,path与path_info相同,难以感知差异;但环境变化后差异才显现。
\n
3) request.get_full_path():path + 查询字符串
\nget_full_path() 返回 path 加上查询字符串 的值。例如:
- \n
/music/bands/the_beatles/?print=true\n
何时有用
\n- \n
- 需要“当前页面不变”的分享/刷新/返回链接 \n
django\n <a href="{{ request.get_full_path }}">刷新链接</a>\n* 登录/权限检查后返回原页面时的 next
django\n <a href="/login/?next={{ request.get_full_path|urlencode }}">登录</a>
\n\n参考:Django 还有
\nget_full_path_info(),其基于path_info。今天不做比较,但了解差异有益。
\n
4) request.build_absolute_uri():包含协议+域名的“完整 URL”
\nbuild_absolute_uri() 根据当前请求生成 绝对 URL(absolute URI)。
大致形式:
\n- \n
https://example.com/music/bands/the_beatles/?print=true\n
何时有用
\n- \n
- 需要域名的链接,例如邮件/聊天分享 \n
- canonical URL、og:url 等元标签 \n
- 向外部系统回调 URL \n
注意事项
\nbuild_absolute_uri() 在构造主机时依赖请求的 Host 信息(内部使用 get_host())。\n这并不一定是实际请求的 URL。在大多数普通场景下,get_host() 的值与实际域名相符,但如果 Nginx 反向代理或 Django 中间件故意使用不同的 tenant host,{{ request.build_absolute_uri }} 的值可能与浏览器实际 URL 不一致。
因此,无论是在 nginx 还是 Django 应用内部实现任何域名相关逻辑时,都应检查部署设置,避免产生意外域名/协议。
\n\n
结论与总结
\n- \n
- 模板中菜单激活 →
request.path\n - 子路径部署/代理环境下稳定比较 →
request.path_info\n - 包含查询字符串的“当前页面不变” →
request.get_full_path()\n - 外部完整链接(含域名) →
request.build_absolute_uri()\n
\n
相关阅读:
\n', '/media/editor_temp/6/c112847e-a9ca-4d58-9a3f-076a20bfbef7.png')