我有一个这样的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模式,这样如果传递了project_id,那么我就可以使用它。
目前的情况是,当我访问不带project_id参数的URL时,会得到404。
有几种方法。
一种是在正则表达式中使用非捕获组:(?:/(?P<title>[a- za -z]+)/)?
Regex 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
可以使用嵌套路由
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")
])),
])),
]
这更加DRY(假设你想将product kwarg重命名为product_id,你只需要更改第4行,它将影响下面的url。
为Django 1.8及以上版本编辑