Django paramètres d'url optionnels
j'ai une url Django comme celle-ci:
url(
r'^project_config/(?P<product>w+)/(?P<project_id>w+)/$',
'tool.views.ProjectConfig',
name='project_config'
),
et mon views.py:
def ProjectConfig(request, product, project_id=None, template_name='project.html'):
...
# do stuff
Le problème est que je veux le project_id paramètre facultatif. Je voudrais que /project_config/
et /project_config/12345abdce/
soient tous deux des modèles d'url également valables, de sorte que si project_id
est passé, alors je peux l'utiliser. En ce moment, j'obtiens une erreur 404 si j'essaie d'accéder à l'url sans le project_id
paramètre.
4 réponses
Il y a plusieurs approches.
L'un est d'utiliser un regex de fantaisie... (?:/(?P<title>[a-zA-Z]+)/)?
rendre un jeton D'URL de Django Regex optionnel
un autre moyen plus facile à suivre est d'avoir plusieurs règles qui correspondent à vos besoins, toutes pointant vers la même vue.
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),
)
gardez à l'esprit que dans votre vue vous aurez également besoin de définir une valeur par défaut pour le paramètre optionnel URL, ou vous obtenir une erreur:
def foo(request, optional_parameter=''):
# Your code goes here
vous pouvez utiliser les routes imbriquées
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")
])),
])),
]
C'est beaucoup plus sec (dites que vous vouliez renommer le product
kwarg en product_id
, vous n'avez qu'à changer la ligne 4, et cela affectera les URLs ci-dessous.
Édité pour Django 1,8 et au-dessus de
encore plus simple à utiliser:
(?P<project_id>\w+|)
La "(a|b)" a ou b, donc dans votre cas il s'agirait d'un ou plusieurs caractères de mot (\w+) ou rien.
donc ça ressemblerait à:
url(
r'^project_config/(?P<product>\w+)/(?P<project_id>\w+|)/$',
'tool.views.ProjectConfig',
name='project_config'
),
a pensé que je voudrais ajouter un peu à la réponse.
si vous avez plusieurs définitions D'URL, vous devrez les nommer séparément. Ainsi, vous perdez la flexibilité lorsque vous appelez reverse car un reverse attendra un paramètre alors que l'autre ne le fera pas.
une autre façon d'utiliser regex pour accommoder le paramètre optionnel:
r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'