Необязательно получить параметры в Django? - PullRequest
25 голосов
/ 30 августа 2009

Может кто-нибудь объяснить, как вы можете написать шаблон URL и представление, которое позволяет необязательные параметры? Я сделал это успешно, но я всегда ломаю тег шаблона URL.

Вот что у меня сейчас:

шаблон

(r'^so/(?P<required>\d+)/?(?P<optional>(.*))/?$', 'myapp.so')

View

def so(request, required, optional):

Если я использую тег шаблона URL в этом примере, предоставляя оба аргумента, он работает просто отлично; однако, если я опущу необязательный аргумент, я получу ошибку в обратном порядке.

Как мне это сделать?

Спасибо, Пит

Ответы [ 7 ]

38 голосов
/ 30 августа 2009

Я обычно делаю два шаблона с именем url :

url(r'^so/(?P<required>\d+)/$', 'myapp.so', name='something'),
url(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', 'myapp.so', name='something_else'),
17 голосов
/ 24 января 2012

URL-адреса Джанго полиморфны:

url(r'^so/(?P<required>\d+)/$', 'myapp.so', name='sample_view'),
url(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', 'myapp.so', name='sample_view'),

очевидно, что вам нужно сделать так:

def sample_view(request, required, optional = None):

так что вы можете назвать его с тем же именем, и он будет работать нормально. Однако учтите, что вы не можете передать None в качестве обязательного аргумента и ожидаете, что он приведет вас к регулярному выражению без аргумента:

Неправильно:

{% url sample_view required optional %}

Правильно:

{% if optional %}
    {% url sample_view required optional %}
{% else %}
    {% url sample_view required %}
{% endif %}

Я не знаю, документировано ли это где-либо - я обнаружил это случайно - я забыл переписать имена URL, и это все равно работало:)

5 голосов
/ 30 августа 2009

Другие продемонстрировали способ справиться с этим с помощью двух отдельных именованных шаблонов URL. Если повторение части шаблона URL вас беспокоит, можно избавиться от него с помощью include ():

url(r'^so/(?P<required>\d+)/', include('myapp.required_urls'))

А затем добавьте файл required_urls.py с:

url(r'^$', 'myapp.so', name='something')
url(r'^(?P<optional>.+)/$', 'myapp.so', name='something_else')

Обычно я бы не считал это стоящим, если бы не было общего префикса для большого количества URL-адресов (определенно более двух).

1 голос
/ 15 мая 2013

Для тех, у кого все еще есть эта проблема. Я использую Django 1.5 (обновлено: использует 1.8), и он все еще работает нормально.

Я использую:

urls.py

url(r'^(?P<app_id>\d+)/start/+(?P<server_id>\d+)?', views.restart, name='restart')

Тогда, когда я хочу получить два URL

/1/start/2

и

/1/start

Я использую:

{% url '<namespace>:start' app.id %}
{% url '<namespace>:start' app.id server.id %}

Это создаст URL

/1/start/2 and 
/1/start/ <- notice the slash.

Если вы создаете URL-адрес вручную, вы должны помнить / *. 1022 *

Обручу это кому-нибудь поможет!

1 голос
/ 30 августа 2009

Почему бы не иметь два шаблона:

(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', view='myapp.so', name='optional'),
(r'^so/(?P<required>\d+)/$', view='myapp.so', kwargs={'optional':None}, name='required'),
0 голосов
/ 11 ноября 2014

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

url/?parameter=foo

назовите это по вашему мнению:

request.REQUEST.get('parameter')

это вернет 'foo'

0 голосов
/ 14 июня 2011

в views.py вы делаете простую вещь.

def so(request, required, optional=None): 

И если вы не получите необязательный параметр в строке URL, в вашем коде будет None.

Просто и элегантно:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...