概要(URLconf=「URL とビューを結びつける交通整理係」)
Django の URLconf(URL configuration)は、
「どの URL にアクセスされたときに、どのビューを呼ぶか」
を決める設定です。
Django の世界では、ユーザーがブラウザで URL を叩くたびに、
まずこの URLconf が「どのビューに処理を渡すか」を判断します。
イメージとしては、
URLconf は「入り口の案内板」、ビューは「実際に仕事をする人」です。
URLconf が「この URL はこの人(ビュー)にお願いね」と振り分けてくれるから、
アプリ全体の動きが整理されます。
ここから、
URLconf の基本構造
プロジェクトレベルとアプリレベルの urls.py の役割
path とパスコンバータ(int:id ( in Bing) など)の意味
include を使った URL の分割設計
名前付き URL と reverse の考え方
を、初心者向けにかみ砕いて説明していきます。
URLconf の基本構造をつかむ
urls.py に書くのは「URLパターンとビューの対応表」
Django プロジェクトを作ると、
プロジェクト直下に project/urls.py ができます。
中身はだいたいこんな形です。
from django.contrib import admin
from django.urls import path
urlpatterns = [
path("admin/", admin.site.urls),
]
Pythonここで大事なのは、urlpatterns という変数です。
これは「URL パターンの一覧」で、
Django はここに書かれた順番に URL を照合していきます。
path("admin/", admin.site.urls) は、
「/admin/ にアクセスされたら admin.site.urls に処理を渡す」
という意味です。
admin.site.urls も実は URLconf なので、
URLconf から別の URLconf にバトンを渡しているイメージです。
URLconf の本質は、
「URL の文字列パターン」と「ビュー(または別の URLconf)」の対応表
だと捉えてください。
path 関数の基本形
path() の基本形はこうです。
path("パス文字列/", 呼び出すビュー, name="任意の名前")
Python例えば、トップページ用のビューがあるとします。
# app/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello Django")
Pythonこれを URL に紐づけるには、urls.py にこう書きます。
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
Python"" は「ルート(/)」を意味します。
これで http://localhost:8000/ にアクセスすると、
index ビューが呼ばれます。
ここで押さえたいのは、
URLconf は「どの URL でどのビューを呼ぶか」を
path() の並びとして書いていく場所
ということです。
プロジェクトレベルとアプリレベルの urls.py
プロジェクト全体の入り口としての project/urls.py
プロジェクトを作ったときにできる project/urls.py は、
「サイト全体の入り口」です。
ユーザーからのリクエストは、まずここに来ます。
ここで、
管理画面は /admin/ に振り分ける
アプリ A は /blog/ 以下に振り分ける
アプリ B は /shop/ 以下に振り分ける
といった「大まかな振り分け」を行います。
例えば、blog アプリと shop アプリがある場合はこう書きます。
# project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("blog/", include("blog.urls")),
path("shop/", include("shop.urls")),
]
Pythoninclude("blog.urls") は、
「/blog/ で始まる URL は、blog アプリの urls.py に続きを任せる」
という意味です。
アプリごとの urls.py で「そのアプリの担当部分」を書く
各アプリ側にも blog/urls.py のようなファイルを作り、
そのアプリに関係する URL をまとめます。
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.post_list, name="post_list"),
path("<int:pk>/", views.post_detail, name="post_detail"),
]
Pythonこれで、
/blog/ → post_list ビュー/blog/1/ → post_detail ビュー(pk=1)/blog/2/ → post_detail ビュー(pk=2)
という対応になります。
この構造のメリットは、
プロジェクト全体の urls.py は「大きな入口の振り分け」だけ
各アプリの urls.py は「そのアプリの中の細かい URL」だけ
と役割を分けられることです。
アプリが増えても、URLconf が整理されたまま保てます。
パスコンバータ(int:id ( in Bing) など)の意味と使い方
URL の一部を「変数」としてビューに渡す
Django の path では、
URL の一部を「変数」としてビューに渡すことができます。
例えば、記事の ID を URL から受け取りたい場合。
# blog/urls.py
urlpatterns = [
path("<int:pk>/", views.post_detail, name="post_detail"),
]
Python<int:pk> の部分が「パスコンバータ」です。
これは、
URL のその部分を整数として解釈し、
ビュー関数の引数 pk に渡す
という意味になります。
ビュー側はこう書きます。
# blog/views.py
from django.http import HttpResponse
def post_detail(request, pk):
return HttpResponse(f"記事ID: {pk}")
Python/blog/10/ にアクセスすると、
pk=10 がビューに渡されます。
よく使うパスコンバータの種類
代表的なものだけ覚えておけば十分です。
<int:pk> 整数<str:slug> 文字列(スラッシュ以外)<slug:slug> スラッグ(英数字とハイフンなど)<path:path> スラッシュを含むパス全体
初心者のうちは、
「ID なら <int:id>、文字列なら <str:name>」
くらいを使いこなせれば OK です。
ここで大事なのは、
URL の一部を「ビューの引数」として受け取れる
そのときに「型」も一緒に指定できる
という感覚です。
include で URL を分割する設計の考え方
URLconf を「モジュール化」する
アプリが増えたり、URL が多くなってくると、
一つの urls.py に全部書くのはつらくなります。
Django の include() は、
URLconf を分割してモジュール化するための仕組みです。
プロジェクトの urls.py では、
大きな入口だけを定義します。
urlpatterns = [
path("admin/", admin.site.urls),
path("blog/", include("blog.urls")),
path("accounts/", include("accounts.urls")),
]
Python各アプリの urls.py では、
そのアプリに関係する URL だけを書きます。
こうすることで、
URL の責任範囲がアプリごとに分かれる
アプリを別プロジェクトに持っていくときも移植しやすい
というメリットが生まれます。
URLconf を設計するときは、
「この URL はどのアプリの責任か」
を意識して、
include でうまく分割していくと、
長期的にかなり楽になります。
名前付き URL と reverse の考え方(ここが実務で超重要)
URL を「文字列」ではなく「名前」で参照する
Django では、URL に name を付けることができます。
# blog/urls.py
urlpatterns = [
path("", views.post_list, name="post_list"),
path("<int:pk>/", views.post_detail, name="post_detail"),
]
Pythonこの name="post_detail" のような名前は、
テンプレートやビューの中で「URL を逆引きする」ために使います。
テンプレートでは、url タグでこう書けます。
<a href="{% url 'post_detail' pk=post.id %}">{{ post.title }}</a>
Pythonここで {% url 'post_detail' pk=post.id %} は、post_detail という名前の URL パターンを探し、
pk に post.id を埋め込んだ URL を生成します。
例えば、post.id が 10 なら /blog/10/ になります。
なぜ「名前で参照する」のが大事なのか
もしテンプレートに直接 /blog/10/ のような URL をベタ書きしてしまうと、
URL パターンを変更したときに、
テンプレートのあちこちを修正しなければなりません。
しかし、name を使っていれば、
path("<int:pk>/", views.post_detail, name="post_detail")
を
path("posts/<int:pk>/", views.post_detail, name="post_detail")
のように変えても、
テンプレート側は {% url 'post_detail' pk=post.id %} のままで OK です。
つまり、
URL の実際の文字列は urls.py に閉じ込める
他の場所(テンプレートやビュー)は「名前」で参照する
という設計にしておくと、
URL の変更に強いアプリになります。
ビュー側でも、reverse() や reverse_lazy() を使って
同じように URL を名前から生成できます。
まとめ(URLconf は「アプリ全体の入り口を設計する場所」)
Django の URLconf を初心者向けに整理すると、こうなります。
URLconf(urls.py)は、「どの URL でどのビューを呼ぶか」を定義する設定で、Django はリクエストが来るたびに urlpatterns を上から順に見て、最初にマッチしたパターンのビューを実行する。
プロジェクトレベルの urls.py は「サイト全体の入り口」を担当し、各アプリの urls.py は「そのアプリの中の URL」を担当する。include() を使うことで URLconf をアプリごとに分割できる。
path() のパスコンバータ(int:pk ( in Bing) など)を使うと、URL の一部をビューの引数として受け取れる。これにより「/blog/10/ → post_detail(pk=10)」のような自然な URL を設計できる。
name を付けた URL を {% url 'name' %} や reverse() で参照することで、「URL の実際の文字列」を urls.py に閉じ込め、他のコードは「名前」だけを知っていればよい状態にできる。

