[英]Django optional url parameters
我有一個像這樣的 Django URL:
url(
r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$',
'tool.views.ProjectConfig',
name='project_config'
),
視圖.py:
def ProjectConfig(request, product, project_id=None, template_name='project.html'):
...
# do stuff
問題是我希望project_id
參數是可選的。
我想/project_config/
和/project_config/12345abdce/
是同樣有效的網址格式,因此,如果project_id
通過,那么我就可以使用它。
目前,當我訪問沒有project_id
參數的 URL 時,我得到 404。
有幾種方法。
一種是在正則表達式中使用非捕獲組: (?:/(?P<title>[a-zA-Z]+)/)?
使正則表達式 Django URL 令牌可選
另一種更容易遵循的方法是擁有多個符合您需求的規則,所有規則都指向同一個視圖。
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 及以上版本編輯
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
類型的可選參數kwargs
的視圖。 在這種情況下,您的視圖不需要屬性project_id
的默認值:
...
path(
'project_config/<product>/',
views.get_product,
kwargs={'project_id': None},
name='project_config'
),
...
有關如何在最新的 Django 版本中完成此操作,請參閱有關 URL 調度的官方文檔。
更簡單的是使用:
(?P<project_id>\w+|)
"(a|b)" 表示 a 或 b,因此在您的情況下,它將是一個或多個單詞字符 (\\w+) 或什么都沒有。
所以它看起來像:
url(
r'^project_config/(?P<product>\w+)/(?P<project_id>\w+|)/$',
'tool.views.ProjectConfig',
name='project_config'
),
以為我會在答案中添加一點。
如果您有多個 URL 定義,則必須分別命名它們。 因此,您在調用 reverse 時失去了靈活性,因為一個反向需要一個參數,而另一個則不需要。
另一種使用正則表達式來容納可選參數的方法:
r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'
姜戈 = 2.2
urlpatterns = [
re_path(r'^project_config/(?:(?P<product>\w+)/(?:(?P<project_id>\w+)/)/)?$', tool.views.ProjectConfig, name='project_config')
]
用 ? 運行良好,您可以檢查pythex 。 記得在視圖方法的定義中添加參數 *args 和 **kwargs
url('project_config/(?P<product>\w+)?(/(?P<project_id>\w+/)?)?', tool.views.ProjectConfig, name='project_config')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.