Параметры необязательного URL-адреса Django
У меня есть URL-адрес Django:
url( r'^project_config/(?P\w+)/(?P\w+)/$', 'tool.views.ProjectConfig', name='project_config' ),
и мои view.py:
def ProjectConfig(request, product, project_id=None, template_name='project.html'): ... # do stuff
Проблема в том, что я хочу, чтобы параметр project_id был необязательным. Я хотел бы, чтобы /project_config/
и /project_config/12345abdce/
были одинаково действительными шаблонами url, поэтому IF project_id
передан, тогда я могу его использовать. Поскольку он стоит на данный момент, я получаю 404, если попытаюсь получить доступ к URL-адресу без параметра project_id
.
- Django South - таблица уже существует
- Динамический путь к файлу в Django
- django - pisa: добавление изображений в PDF-файл
- Как получить текущий URL-адрес в шаблоне Django?
- Как переименовать элементы в значениях () в Django?
- Django lazy QuerySet и разбиение на страницы
- django - почему объект request.POST неизменяем?
- Принимать только определенный тип файла в FileField, на стороне сервера
- Django: разрешение отклонено при попытке доступа к базе данных после восстановления (миграции)
- загрузка нескольких файлов с использованием того же имени ввода в django
- Как принудительно выйти из системы в django?
- Пользовательские менеджеры Django - как мне вернуть только объекты, созданные зарегистрированным пользователем?
- Django - простой пример тега шаблона
Существует несколько подходов.
Один из них – использовать причудливое регулярное выражение … (?:/(?P
Создание маркера URL-адреса регулярного выражения Django
Другой, более простой путь – это иметь несколько правил, которые соответствуют вашим потребностям, и все они указывают на одно и то же представление.
urlpatterns = patterns('', url(r'^project_config/$', views.foo), url(r'^project_config/(?P\w+)/$', views.foo), ulr(r'^project_config/(?P \w+)/(?P\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\w+)$', include(patterns('', url(r'^$', ProductView.as_view(), name="product"), url(r'^(?P\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\w+)$', include([ url(r'^$', ProductView.as_view(), name="product"), url(r'^(?P\w+)$', ProjectDetailView.as_view(), name="project_detail") ])), ])), ]
Это намного больше DRY (скажем, вы хотели переименовать product
kwarg в product_id
, вам нужно только изменить строку 4, и это повлияет на приведенные ниже URL-адреса.
Отредактировано для Django 1.8 и выше
Еще проще использовать:
(?P\w+|)
«(A | b)» означает a или b, поэтому в вашем случае это будет один или несколько символов слова (\ w +) или ничего.
Таким образом, это будет выглядеть так:
url( r'^project_config/(?P\w+)/(?P\w+|)/$', 'tool.views.ProjectConfig', name='project_config' ),
Думал, я бы добавил немного ответа.
Если у вас несколько определений URL-адресов, вам нужно будет указать их отдельно. Таким образом, вы теряете гибкость при вызове reverse, поскольку один обратный будет ожидать параметр, а другой – нет.
Другой способ использования регулярного выражения для размещения необязательного параметра:
r'^project_config/(?P\w+)/((?P\w+)/)?$'