2009-08-19 3 views
20

У меня есть шаблон URL-адреса, как это:Поднять 404 и продолжить URL цепи

urlpatterns = (
    url(r'^$', list_titles, name='list'), 
    url(r'^(?P<tag>[a-z\-0-9]+?)/$', list_titles, name='filtered-list'), 
    url(r'^(?P<title>\S+?)/$', show_title, name='title'), 
) 

filtered-list и title матч одни и те же вещи.

Если есть список товаров, соответствующих tag в filtered-list, я хочу, чтобы list_titles сработал. Но если нет подходящего tag, я хочу вернуть его обратно в процессор URL так, чтобы show_title срабатывает.

Если подходящего названия нет, я создам соответствующий 404.

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

ответ

30

Это, безусловно, логика взглядов; all urls.py предназначен для сопоставления шаблонов URL, не выполняющих проверку. Вы можете использовать исключение Http404, чтобы справиться с этим.

from django.http import Http404 

def detail(request, poll_id): 
    try: 
     p = Poll.objects.get(pk=poll_id) 
    except Poll.DoesNotExist: 
     raise Http404 
    return render_to_response('polls/detail.html', {'poll': p}) 

В качестве альтернативы, вы можете найти get_object_or_404 или get_list_or_404 методы, которые сокращают его немного.


Обещанное редактирование следует. Не совсем то, что вы ищете, но ...

urlpatterns = (
    url(r'^$', list_titles, name='list'), 
) 

if 1=1: # Your logic here 
    urlpatterns += (url(r'^$', list_titles, name='list'),) 

urlpatterns += (
    url(r'^(?P<title>\S+?)/$', show_title, name='title'), 
    url(r'^spam/$', spam_bar), 
    url(r'^foo/$', foo_bar), 
} 
+0

спасибо за get_list_or_404, но это не так ответ на мой вопрос. Я говорю, если я не могу получить список заголовков на основе URL-адреса, я хочу, чтобы URL-адрес был переоценен через остальные URL-адреса. – Oli

+0

Хм ... Понимаю. Ваш первоначальный вопрос не был ужасно ясным. Помните, что urls.py - это всего лишь код Python, поэтому вы можете сделать там какую-то проверку. Дайте мне минуту, и я отредактирую свой ответ. – 2009-08-19 13:04:08

+1

'raise Http404', вероятно, должен быть' raise Http404() ': https://docs.djangoproject.com/en/2.0/topics/http/views/#the-http404-exception –