Djangoのルーティング層と高度な機能

ルーティングの基本とURLの処理

Djangoにおけるルーティングは、URLとビュー関数の対応関係を定義する仕組みです。URLの末尾にスラッシュがあるかどうかによって挙動が変わるため、設定ファイルsettings.pyAPPEND_SLASH = Falseを設定することで、スラッシュなしのリクエストを自動でリダイレクトしないように調整可能です。

基本的なルーティング構文:

from django.urls import path
from . import views

urlpatterns = [
    path('index/', views.index),
]

動的URLとpath変換器

Django 2.x以降では、URLの一部を動的に扱うためにpath変換器が提供されています。例えば、整数や文字列を抽出する際に利用します。

path('user//', views.user_detail),
path('article//', views.article_detail)
  • int: 正の整数または0
  • str: パス区切り文字以外の文字列
  • slug: 英数字とハイフン、アンダースコア
  • uuid: UUID形式
  • path: 任意のパス全体

正規表現によるルーティング

複雑なURLのパターンを扱うにはre_pathを使用します。これはDjango 1.xのurl()と同等の機能です。

from django.urls import re_path
from . import views

urlpatterns = [
    re_path(r'^test/$', views.test),
    re_path(r'^test/(\d{4})/$', views.test_year),
    re_path(r'^test/(?P<year>\d{4})/$', views.test_named_year),
]
  • 無名グループ:(\d{4}) → 位置引数としてビューに渡される
  • 有名グループ:(?P\d{4}) → キーワード引数としてビューに渡される

※無名グループと有名グループは混在させることができません。

逆引き(リバース)ルーティング

URLの変更に対応するために、ルーティングに名前を付けて逆引きする機能です。

path('login/', views.login, name='login_page')
  • テンプレート内:{% url 'login_page' %}
  • ビュー関数内:from django.shortcuts import reverse; reverse('login_page')

動的URLの逆引き:

path('profile//', views.profile, name='profile_page')
  • テンプレート:{% url 'profile_page' 'alice' %}
  • ビュー関数:reverse('profile_page', args=['alice'])

ルーティングの分離とアプリケーションの分割

大規模なプロジェクトでは、すべてのルーティングを1つのファイルに書くのは管理が困難です。Djangoではアプリケーションごとにurls.pyを設け、メインルーティングでinclude()を使って分離できます。

# メインurls.py
from django.urls import include, path

urlpatterns = [
    path('blog/', include('blog.urls')),
    path('shop/', include('shop.urls')),
]

名前空間と逆引きの競合回避

複数アプリケーションで同じ名前のルーティングが存在する場合、名前空間を指定することで区別できます。

# メインurls.py
path('blog/', include('blog.urls', namespace='blog')),
path('shop/', include('shop.urls', namespace='shop')),

# blog/urls.py
app_name = 'blog'
urlpatterns = [
    path('post//', views.post_detail, name='detail'),
]

# shop/urls.py
app_name = 'shop'
urlpatterns = [
    path('product//', views.product_detail, name='detail'),
]
  • ビュー関数内:reverse('blog:detail', args=[10])
  • テンプレート:{% url 'shop:detail' 5 %}

名前空間を使わず、名前をアプリケーション名でプレフィックスする方法もあります:

path('post//', views.post_detail, name='blog_detail')

タグ: Django web-framework Python url-routing reverse-routing

9月6日 22:51 投稿