# 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 }}` はどこから来るのか {#sec-e3874691b2fc} テンプレートで `{{ request }}` が使えるのは、通常 **request context processor** が有効になっているためです。 * `django.template.context_processors.request` がテンプレートコンテキストに `request` を注入します。 * `TEMPLATES` 設定の `OPTIONS['context_processors']` に登録されていると動作します。 Django はこのプロセッサをデフォルトで有効にしていることが多いので、特別に設定を触らなくても `{{ request }}` を自然に使えます。 `request` は、Django がリクエストを受け取ったときに生成する `HttpRequest`(実際には WSGI/ASGI のサブクラス)で、ビューへ渡されます。`path` や `path_info` などの属性もここに含まれます。 ![Djangoという名前のマジシャンが帽子から道具を取り出すイメージ](/media/editor_temp/6/c112847e-a9ca-4d58-9a3f-076a20bfbef7.png) --- ## ひと目で覚える 4 つの違い {#sec-0f722c9bd67c} * **`path`**:ドメインなしのパスだけ * **`path_info`**:アプリが見る「実際のパス」(script prefix を除外) * **`get_full_path()`**:`path` + クエリ文字列 * **`build_absolute_uri()`**:スキーム + ホスト + パス + クエリ文字列(完全な URL) それでは順に見ていきます。 --- ## 1) `request.path`:ドメインなしの「パス」 {#sec-26a629a2d24e} `request.path` はスキームやホストを含まず、パスだけを返します。 * `/music/bands/the_beatles/` ### いつ役立つか {#sec-b307f735685f} * メニューのアクティブ化など、単純な一致判定 ```django {% if request.path == "/settings/" %}active{% endif %} ``` * 「どのカテゴリ配下か?」のようなプレフィックス判定 ```django {% if request.path|slice:":5" == "/api/" %}...{% endif %} ``` --- ## 2) `request.path_info`:環境に左右されにくい「実際のパス」 {#sec-fd1e8e14948f} Django のドキュメントでは次の点がポイントです。 * サーバ構成によっては URL が **script prefix(`SCRIPT_NAME`)** と **path info** に分かれることがある * `path_info` はそのうち **path info 部分を常に含む**ため、環境依存が少ない 例えばアプリを `/app` のようなプレフィックス配下にマウントする(リバースプロキシ、サブパスデプロイなど)構成では、`path` と `path_info` が異なることがあります。 ### いつ役立つか {#sec-2985f0c9cd7c} * サブパス配下で動く環境で、アプリ基準のパスとして扱いたいとき * テストと本番でプレフィックスが変わる可能性があるとき > ルート(`/`)直下で動かしている間は `path` と `path_info` が同じになりやすく、違いに気づきにくいです。 --- ## 3) `request.get_full_path()`:パス + クエリ文字列 {#sec-1364e4e65388} `get_full_path()` は **パスにクエリ文字列を含めたもの**を返します。 * `/music/bands/the_beatles/?print=true` ### いつ役立つか {#sec-0ac89fe1b7cd} * 「現在のページそのまま」のリンクが必要なとき(共有、リフレッシュ、戻るなど) ```django リフレッシュリンク ``` * ログインや権限チェック後に戻す `next` を作りたいとき ```django ログイン ``` > なお Django には `get_full_path_info()` もあります。こちらは `path_info` ベースです(本記事では詳細は扱いません)。 --- ## 4) `request.build_absolute_uri()`:スキームとホストまで含む「完全な URL」 {#sec-0ba80b4c4700} `build_absolute_uri()` は現在のリクエストを基に、**絶対 URL(absolute URI)**を組み立てます。 * `https://example.com/music/bands/the_beatles/?print=true` ### いつ役立つか {#sec-428d3d6b9613} * メールやメッセンジャーなど、ドメイン付き URL が必要な共有リンク * canonical URL、`og:url` などのメタタグ * 外部システムへ渡すコールバック URL ### 注意すべき点 {#sec-b24dccc132d6} `build_absolute_uri()` は、ホスト情報を `get_host()` から取得して URL を作ります。つまり、**ブラウザが実際に表示している URL と常に一致するとは限りません**。 特に次のような場合は要注意です。 * Nginx などのリバースプロキシ配下で Host/Proto ヘッダをどう渡しているかが環境次第 * テナント機構などで、アプリ側でホスト判定・書き換えロジックを持っている ドメインやスキーム周りの設定(プロキシのヘッダ設定、Django 側の関連設定)も合わせて確認するのが安全です。 --- ## まとめ {#sec-bd7ea169a316} * **メニューのアクティブ判定** → `request.path` * **サブパス配下でも安定して比較したい** → `request.path_info` * **クエリ文字列まで含めて「現在のページそのまま」** → `request.get_full_path()` * **外部に出す完全な URL(ドメイン込み)** → `request.build_absolute_uri()` --- **関連記事**: * [リバースプロキシとは?フォワードプロキシとの違い、目的、使用シナリオを一目で整理](/whitedec/2025/12/10/reverse-proxy-forward-proxy-differences/) * [Django を最初から再学習する:HTTP から始める学習ロードマップ](/whitedec/2025/12/22/django-first-learning-roadmap/)