Django可选URL参数

pdsfdshx  于 2023-02-17  发布在  Go
关注(0)|答案(7)|浏览(152)

我有一个Django的网址,如下所示:

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/是同样有效的URL模式,这样如果传递了project_id那么我就可以使用它。
就目前情况而言,当我在没有project_id参数的情况下访问URL时,我会得到一个404。

9bfwbjaz

9bfwbjaz1#

有几种方法。
一种是在正则表达式中使用非捕获组:(?:/(?P<title>[a-zA-Z]+)/)?
Making a Regex Django URL Token Optional
另一种更容易遵循的方法是拥有多个符合您需求的规则,所有规则都指向同一个视图。

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
vhmi4jdf

vhmi4jdf2#

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(),您还可以使用可选参数kwargsdict类型)将额外参数传递给视图。在这种情况下,您的视图不需要属性project_id的默认值:

...
    path(
        'project_config/<product>/',
        views.get_product,
        kwargs={'project_id': None},
        name='project_config'
    ),
    ...
  • 在Django的最新版本中是如何实现的,请参见关于URL调度的官方文档。*
zlhcx6iw

zlhcx6iw3#

您可以使用嵌套路由

  • 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及以上版本编辑 *
q0qdq0h2

q0qdq0h24#

更简单的方法是:

(?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'
),
h9a6wy2h

h9a6wy2h5#

我想我得在答案上加一点。
如果你有多个URL定义,那么你必须分别命名它们,这样你就失去了调用reverse的灵活性,因为一个reverse需要一个参数,而另一个不需要。
使用regex来容纳可选参数的另一种方法是:

r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'
wbrvyc0a

wbrvyc0a6#

Django = 2.2

urlpatterns = [
    re_path(r'^project_config/(?:(?P<product>\w+)/(?:(?P<project_id>\w+)/)/)?$', tool.views.ProjectConfig, name='project_config')
]
iibxawm4

iibxawm47#

使用?效果很好,您可以检查pythex。记得在视图方法的定义中添加参数 *args和**kwargs

url('project_config/(?P<product>\w+)?(/(?P<project_id>\w+/)?)?', tool.views.ProjectConfig, name='project_config')

相关问题