Django 模板中取得 URL:request.path vs path_info vs get_full_path() vs build_absolute_uri()

在 Django 模板中,常常需要取得目前頁面的 URL,例如:

  • 導覽列「目前選單高亮」
  • 登入後「回到原本頁面(next)」
  • 建立 canonical URL 或分享連結
  • 連到「包含查詢字串、完全相同的當前頁面」

除了 {{ request.path }},還有幾個容易混淆的屬性/方法。本文整理比較以下四個:

  • request.path
  • request.path_info
  • request.get_full_path()
  • request.build_absolute_uri()

{{ request }} 是從哪裡來的?{#sec-e3874691b2fc}



在模板中看到 {{ request }},通常表示 request context processor 已啟用。

  • django.template.context_processors.request 會把 request 物件放進模板上下文。
  • 只要在 TEMPLATES 設定的 OPTIONS['context_processors'] 中啟用,它就會生效。

一般情況下,Django 預設就包含這個 processor,所以多數專案不需要額外設定;除非你刻意把它移除。

request 物件本身是 Django 接到請求後建立的 HttpRequest(實際上是 WSGI/ASGI 的子類),並傳到 view。它包含 pathpath_info 等屬性。

Django 這位魔術師從帽子裡抽出工具的圖像


一句話記住四個差異

  • path:去掉域名/協定,只剩路徑
  • path_info:應用程式看到的實際路徑(不含 script prefix)
  • get_full_path()path + 查詢字串
  • build_absolute_uri():完整 URL(協定 + 主機 + 路徑 + 查詢字串)

1) request.path:無域名的「路徑」



request.path 只回傳路徑,不含協定或域名,例如:

  • /music/bands/the_beatles/

何時有用?

  • 菜單高亮等簡單比較
{% if request.path == "/settings/" %}active{% endif %}
  • 用前綴判斷類別(例如 API 區)
{% if request.path|slice:":5" == "/api/" %}...{% endif %}

2) request.path_info:部署環境中更穩定的「實際路徑」

Django 文件的重點是:

  • 某些伺服器配置會把 URL 分成 script prefix(SCRIPT_NAMEpath info
  • path_info 永遠是 path info 那一段,因此比較不受環境影響。

如果你的應用程式掛在 /app 之類的前綴下(反向代理、子路徑部署),pathpath_info 就可能不同。

何時有用?

  • 子路徑部署(如 /app/)需要用「應用程式視角」的路徑判斷
  • 測試/正式環境的前綴可能不同

若只在根目錄 (/) 運行,兩者往往相同,因此容易忽略差異。


3) request.get_full_path()path + 查詢字串

get_full_path() 會回傳路徑加上查詢字串,例如:

  • /music/bands/the_beatles/?print=true

何時有用?

  • 需要「當前頁面原樣」的分享/重新整理/返回連結
<a href="{{ request.get_full_path }}">重新整理連結</a>
  • 建立登入後返回用的 next
<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,例如:

  • https://example.com/music/bands/the_beatles/?print=true

何時有用?

  • 電子郵件/訊息分享(需要完整域名)
  • canonical URL、og:url 等 meta 標籤
  • 提供外部系統 callback URL

注意事項

build_absolute_uri() 依賴請求中的 Host 資訊(內部使用 get_host()),因此不一定等同於使用者瀏覽器實際看到的 URL。在反向代理(例如 Nginx)或多租戶(tenant)等自訂主機邏輯下,產生結果可能不同。使用前請確認你的部署與 proxy 設定。


總結

  • 模板中菜單高亮request.path
  • 子路徑部署/代理環境下穩定比較request.path_info
  • 包含查詢字串的當前頁面request.get_full_path()
  • 對外完整連結(含域名)request.build_absolute_uri()

相關文章