Дополнительные параметры url-адреса Django


у меня есть url Django, как это:

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 передается, то я могу использовать его. Как это стоит на данный момент, я получаю 404, если я пытаюсь получить доступ к url без

4 130

4 ответа:

есть несколько подходов.

- Это необычные выражения... (?:/(?P<title>[a-zA-Z]+)/)?
сделать регулярное выражение Django URL Token необязательным

другой, более простой способ-иметь несколько правил, которые соответствуют вашим потребностям, все они указывают на один и тот же вид.

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

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, то вам придется назвать каждый из них отдельно. Таким образом, вы теряете гибкость при вызове обратного, так как один обратный будет ожидать параметр, а другой-нет.

другой способ использовать регулярное выражение для размещения необязательного параметра:

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