Django可选的url参数
我有这样的Djangourl:
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模式,所以如果 project_id
被传递,那么我可以使用它。 就目前而言,如果我尝试访问没有project_id
参数的url,我会得到一个404。
有几种方法。
一个是使用一个奇特的正则expression式… (?:/(?P<title>[a-zA-Z]+)/)?
使正则expression式Django URL令牌可选
另一个更容易遵循的方式是有多个符合你需求的规则,都指向相同的观点。
urlpatterns = patterns('', url(r'^project_config/$', views.foo), url(r'^project_config/(?P<product>\w+)/$', views.foo), ulr(r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$', views.foo), )
请记住,在您的视图中,您还需要为可选的URL参数设置默认值,否则会出现错误:
def foo(request, optional_parameter=''): # Your code goes here
你可以使用嵌套的路线
Django <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") ))), ))), )
Django> = 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") ])), ])), ]
这是更多的干(如果你想重命名product
kwarg到product_id
,你只需要改变第4行,这将影响下面的url。
编辑为Django 1.8及以上
更简单的是使用:
(?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定义,那么您必须分别命名每个url。 所以你在调用反向时会失去灵活性,因为一个反向会期望一个参数,而另一个则不会。
另一种使用正则expression式来容纳可选参数的方法:
r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'