[Django] 2系から導入されたパスコンバータとは

Djangoの2系からは新たにパスコンバータと呼ばれる機能が追加されました。

パスコンバータとは

Django1系ではURLのルーティングを正規表現で行なっていました。

url(r"[0-9]+/", views.integer, name="integer")

2系ではパスコンバータを用いてより簡単にURLのルーティングを記述できます。

path("<int>/", views.integer, name="integer")

使い方

パスコンバータはpath関数の中で利用可能です。

<>の中にパスコンバータの名前を入れて:で識別名を付けることができます。

数字をマッチさせてidという名前を付ける例

"<int:id>"
# 一系の(?P<id>[0-9]+)に相当

Django2.1現在パスコンバータは以下のものが利用可能です。

int

0以上、一桁以上の正の整数とマッチ

path("<int>/", views.integer, name="integer")
# 数値とマッチする以下と同等
# url(r"^[0-9]+/$", views.integer, name="integer")

str

/除く、空ではない文字列にマッチ

path("<str>/", views.string, name="string")
# 以下と同等
# url(r"^[^/]+/$", views.string, name="string")

slug

大文字小文字のアルファベットと数字、-ハイフン、_アンダースコア、にマッチ

path("<slug>/", views.slug, name="slug")
# 以下と同等
# url(r"^[-a-zA-z0-9_]+/$", views.slug, name="slug")

uuid

uuid(8-4-4-12の半角小英数字)の形式にマッチ

path('<uuid>/', views.uuid, name="uuid")
# 以下と同等
# url(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/$', views.uuid, name="uuid")

path

/含む、空ではないすべての文字列にマッチ

path('<path>/', views.path, name="path")
# 以下と同等
# url(r'^.+/$', views.path, name="path")

なお、パスコンバータと正規表現を混ぜることはできないので注意してください。

path(r"<int>/.+?/", views.mix, name="mix") # 正規表現と混ぜちゃダメ

自作

パスコンバータはもともと用意されているもののほかに自作することも可能です。
my_converter.py

class FourDigitYearConverter:
    regex = '[0-9]{4}'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return "{:4d}".format(value)

urls.py

from django.urls import register_converter, path
from . import myconverter, views

# ここで定義したパスコンバータを有効化
register_converter(converter.FourDigitYearConverter, "year")

urlpatterns = [
    path('articles/<year:year>/', views.year_archive),
]