views:

178

answers:

1

I've got a URLs pattern like this:

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'),
)

The filtered-list and title match the same things.

If there is is a available list of things matching the tag in filtered-list, I want list_titles to fire off. But if there isn't an matching tag, I want to bubble that back to the URL processor so show_title fires off.

If there's no matching title, I'll raise a proper 404 there.

I have a feeling this might have something to do with signals... But I've never used them before, so I could be completely off on that =)

Note: I know I can do this from inside the view... But it's a bit smelly having to hard-wire the process into the view. I'd like the URL order to decide what gets chosen first and what it hands off to.

Edit: I'm an idiot.

This is exactly what happens by default! As long as you have a proper match. My show_title method was missing its title argument so the third URL wasn't being passed in properly.

Ok, so a slightly modified question: knowing now that there is exception handling built into it, would it be more efficient for me to manually pass the request to show_title (from within list_titles, or would it be, on balance, better to leave the urlpatterns handling things?

Edit2: Revenge of the idiot

Turns out it doesn't do this at all. I accidentally modified the first pattern so it wasn't matching at all, and thought it was handing off to the detail view. One of those days, I'm afraid.

+1  A: 

This is certainly view logic; all urls.py is for is for matching URL patterns, not performing validation. You can use the Http404 exception to handle this.

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

Alternatively, you may find the get_object_or_404 or get_list_or_404 methods, which shorten it up a bit.


Promised edit follows. Not exactly what you're looking for, but...

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),
}
cpharmston
thanks for get_list_or_404 but this isn't an answer so much to my question. I'm saying if I can't get a list of titles based on the URL, I want the URL to be re-evaluated through the rest of the URLs.
Oli
Hmm...I see. Your original question wasn't terribly clear. Remember that the urls.py is just Python code, so you can do some sort of validation there. Give me a minute and I'll edit my answer.
cpharmston