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

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