2009-08-19 16 views
20

Mam wzorzec URL tak:Podnieść 404 i kontynuować łańcuch 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 i title mecz te same rzeczy.

Jeśli dostępna jest lista rzeczy pasujących do tag w filtered-list, chcę, aby list_titles wystrzelił. Ale jeśli nie ma pasującego tag, chcę sparować to z powrotem do procesora adresu URL, aby odpalić show_title.

Jeśli nie ma pasującego tytułu, podniosę odpowiedni 404 tam.

Wiem, że mogę to zrobić z wnętrza widoku ... ale jest to trochę śmierdzące, ponieważ trzeba mocno podłączyć proces do widoku. Chciałbym, aby kolejność adresów URL decydowała o tym, co zostanie wybrane jako pierwsze i do czego służy.

Odpowiedz

30

To z pewnością logika widoku; wszystko, do czego służy urls.py, to pasujące wzorce adresów URL, bez sprawdzania poprawności. Możesz użyć wyjątku Http404, aby sobie z tym poradzić.

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}) 

Alternatywnie, można znaleźć get_object_or_404 lub get_list_or_404 metod, które skracają go trochę.


Następuje obiecana edycja. Nie dokładnie to, czego szukasz, ale ...

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

dzięki za get_list_or_404, ale to nie jest odpowiedź na moje pytanie. Twierdzę, że jeśli nie mogę uzyskać listy tytułów na podstawie adresu URL, chcę, aby adres URL został ponownie oceniony przez resztę adresów URL. – Oli

+0

Hmm ... Rozumiem. Twoje pierwotne pytanie nie było strasznie jasne. Pamiętaj, że urls.py to po prostu kod Pythona, więc możesz tam przeprowadzić jakąś walidację. Daj mi chwilę, a ja poprawię odpowiedź. –

+1

'raise Http404' powinno prawdopodobnie być' podniesieniem Http404() ': https://docs.djangoproject.com/en/2.0/topics/http/views/#the-http404-exception –