Django テンプレートで URL を取得する方法:request.path vs path_info vs get_full_path vs build_absolute_uri

Django テンプレートで「いま見ている URL」を使いたい場面はよくあります。

  • ナビゲーションで現在の項目をアクティブにする
  • ログイン後に元のページへ戻す(next
  • canonical URL や共有リンクを作る
  • クエリ文字列まで含めて「現在のページそのまま」をリンクにする

ただ、{{ request.path }} 以外にも似た属性がいくつかあり、混乱しがちです。ここでは次の 4 つを整理して比較します。

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

{{ request }} はどこから来るのか

テンプレートで {{ request }} が使えるのは、通常 request context processor が有効になっているためです。

  • django.template.context_processors.request がテンプレートコンテキストに request を注入します。
  • TEMPLATES 設定の OPTIONS['context_processors'] に登録されていると動作します。

Django はこのプロセッサをデフォルトで有効にしていることが多いので、特別に設定を触らなくても {{ request }} を自然に使えます。

request は、Django がリクエストを受け取ったときに生成する HttpRequest(実際には WSGI/ASGI のサブクラス)で、ビューへ渡されます。pathpath_info などの属性もここに含まれます。

Djangoという名前のマジシャンが帽子から道具を取り出すイメージ


ひと目で覚える 4 つの違い

  • 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 %}
  • 「どのカテゴリ配下か?」のようなプレフィックス判定
{% 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 が異なることがあります。

いつ役立つか

  • サブパス配下で動く環境で、アプリ基準のパスとして扱いたいとき
  • テストと本番でプレフィックスが変わる可能性があるとき

ルート(/)直下で動かしている間は pathpath_info が同じになりやすく、違いに気づきにくいです。


3) request.get_full_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(absolute URI)を組み立てます。

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

いつ役立つか

  • メールやメッセンジャーなど、ドメイン付き URL が必要な共有リンク
  • canonical URL、og:url などのメタタグ
  • 外部システムへ渡すコールバック URL

注意すべき点

build_absolute_uri() は、ホスト情報を get_host() から取得して URL を作ります。つまり、ブラウザが実際に表示している URL と常に一致するとは限りません

特に次のような場合は要注意です。

  • Nginx などのリバースプロキシ配下で Host/Proto ヘッダをどう渡しているかが環境次第
  • テナント機構などで、アプリ側でホスト判定・書き換えロジックを持っている

ドメインやスキーム周りの設定(プロキシのヘッダ設定、Django 側の関連設定)も合わせて確認するのが安全です。


まとめ

  • メニューのアクティブ判定request.path
  • サブパス配下でも安定して比較したいrequest.path_info
  • クエリ文字列まで含めて「現在のページそのまま」request.get_full_path()
  • 外部に出す完全な URL(ドメイン込み)request.build_absolute_uri()

関連記事