次のようなDjango URLがあります。
url(
r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$',
'tool.views.ProjectConfig',
name='project_config'
),
views.py:
def ProjectConfig(request, product, project_id=None, template_name='project.html'):
...
# do stuff
問題は、project_id
パラメーターをオプションにすることです。
/project_config/
と/project_config/12345abdce/
を等しく有効なURLパターンにしたいので、ifproject_id
が渡され、then使用できます。
現時点では、project_id
パラメーターなしでURLにアクセスすると404が表示されます。
いくつかのアプローチがあります。
1つは、正規表現で非キャプチャグループを使用することです:(?:/(?P<title>[a-zA-Z]+)/)?
正規表現の作成Django URLトークンはオプション
もう1つの簡単な方法は、ニーズに一致する複数のルールを作成し、すべて同じビューを指すようにすることです。
urlpatterns = patterns('',
url(r'^project_config/$', views.foo),
url(r'^project_config/(?P<product>\w+)/$', views.foo),
url(r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$', views.foo),
)
ビューでは、オプションのURLパラメーターのデフォルトも設定する必要があることに注意してください。そうしないと、エラーが発生します。
def foo(request, optional_parameter=''):
# Your code goes here
ネストされたルートを使用できます
ジャンゴ<1.8
urlpatterns = patterns(''
url(r'^project_config/', include(patterns('',
url(r'^$', ProjectConfigView.as_view(), name="project_config")
url(r'^(?P<product>\w+)$', include(patterns('',
url(r'^$', ProductView.as_view(), name="product"),
url(r'^(?P<project_id>\w+)$', ProjectDetailView.as_view(), name="project_detail")
))),
))),
)
ジャンゴ> = 1.8
urlpatterns = [
url(r'^project_config/', include([
url(r'^$', ProjectConfigView.as_view(), name="project_config")
url(r'^(?P<product>\w+)$', include([
url(r'^$', ProductView.as_view(), name="product"),
url(r'^(?P<project_id>\w+)$', ProjectDetailView.as_view(), name="project_detail")
])),
])),
]
これはさらに多くのDRY(product
kwargの名前をproduct_id
に変更したい場合、行4を変更するだけで、以下のURLに影響します。
Django 1.8以降用に編集済み
さらに簡単です:
(?P<project_id>\w+|)
「(a | b)」はaまたはbを意味するため、あなたの場合は1つ以上のWord文字(\ w +)か、何もありません。
したがって、次のようになります。
url(
r'^project_config/(?P<product>\w+)/(?P<project_id>\w+|)/$',
'tool.views.ProjectConfig',
name='project_config'
),
答えに少し追加すると思いました。
複数のURL定義がある場合は、それぞれに個別に名前を付ける必要があります。そのため、1つのリバースはパラメーターを期待し、もう1つのリバースはパラメーターを期待しないため、リバースを呼び出すときに柔軟性が失われます。
正規表現を使用してオプションのパラメーターに対応する別の方法:
r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'
Django> 2.0バージョン:
このアプローチは、基本的に Yuji 'Tomita' Tomita's Answer に記載されているものと同じです。ただし、影響を受ける構文は次のとおりです。
# URLconf
...
urlpatterns = [
path(
'project_config/<product>/',
views.get_product,
name='project_config'
),
path(
'project_config/<product>/<project_id>/',
views.get_product,
name='project_config'
),
]
# View (in views.py)
def get_product(request, product, project_id='None'):
# Output the appropriate product
...
path
を使用すると、 ビューに追加の引数を渡す をオプションの引数としてdict
とともに使用することもできます。この場合、ビューには属性project_id
のデフォルトは必要ありません。
...
path(
'project_config/<product>/',
views.get_product,
name='project_config',
{'project_id': None}
),
...
これがどのように行われるかについて最新のDjangoバージョンで、 公式URLディスパッチに関するドキュメント 。
ジャンゴ= 2.2
urlpatterns = [
re_path(r'^project_config/(?:(?P<product>\w+)/(?:(?P<project_id>\w+)/)/)?$', tool.views.ProjectConfig, name='project_config')
]