Django 模板中获取 URL:request.pathpath_infoget_full_pathbuild_absolute_uri 的区别

在 Django 模板中,经常需要获取当前 URL。

  • 导航栏“当前菜单激活”
  • 登录后“返回原来页面(next)”
  • 生成 canonical URL / 分享链接
  • 包含查询字符串的“当前页面不变”链接

然而,除了 {{ request.path }},还有许多类似的属性,容易混淆。今天我们将清晰比较下面四个常用属性。

  • request.path
  • request.path_info
  • request.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 请求子类),并将其传递给视图。该对象包含 pathpath_info 等属性。

Django 这个名字的魔术师从帽子里拿出工具的图片


一句话总结:四个属性的记忆方式

  • 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 等前缀下(反向代理、子路径部署等)时,pathpath_info 可能不同。

何时有用

  • 需要考虑子路径部署(如 /app/)时,想用“应用基准路径”判断
  • 测试/生产服务器前缀可能不同

通常在单域名根路径(/)下运行时,pathpath_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()

相关阅读