我有一个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/
是同样有效的网址格式,因此, 如果 project_id
通过, 那么我就可以使用它。
因为它代表的那一刻,我收到了404,当我访问的网址不project_id
参数。
Answer 1:
有几种方法。
一种方法是使用在正则表达式的非捕获组: (?:/(?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
Answer 2:
您可以使用嵌套路线
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行,它会影响到下面的网址。
编辑Django的1.8及以上
Answer 3:
更简单的使用方法:
(?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'
),
Answer 4:
以为我会有点添加到答案。
如果你有多个URL的定义,那么你就必须单独命名他们每个人。 所以,你叫反向时,因为一个倒车指望一个参数,而其他不会失去灵活性。
另一种方法是使用正则表达式来适应可选参数:
r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'
Answer 5:
Django的> 2.0版 :
该方法是在给定的一个基本相同的虞姬“富田”富田的答案 。 受此影响,然而,这是语法:
# 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调度的官方文档 。
Answer 6:
Django的= 2.2
urlpatterns = [
re_path(r'^project_config/(?:(?P<product>\w+)/(?:(?P<project_id>\w+)/)/)?$', tool.views.ProjectConfig, name='project_config')
]
文章来源: Django optional url parameters