Calling reverse in Django

The reusable-applications-convention says that you should provide a “success_url” parameter for your views so that you can override it from the urlconf.

The DRY principle says that you should always use reverse() instead of hard-coding URLs in your code.

The problem is that you can’t use reverse in your urlconf!

If you try to use reverse in the urlconf, it will spit out an error The included urlconf foo.urls doesn’t have any patterns in it, which really is not helping much…

in fact you’re probably gonna waste at least 15 minutes trying to prove that there are patterns in your urlconf.

The solution

I guess the problem has something to do with the fact that django needs to know everything about your url structure before it can reverse() anything, and since you’re trying to reverse() something while defining your url structure, it doesn’t know what the hell is going on.

What you gotta do is use lazy reverse:

( Quoting akaihola from http://code.djangoproject.com/ticket/5925 )

from django.conf.urls.defaults import *
from django.core.urlresolvers import reverse
from django.utils.functional import lazy
from django.http import HttpResponse

reverse_lazy = lazy(reverse, unicode)

urlpatterns = patterns('',
url(r'^comehere/', lambda request: HttpResponse('Welcome!'), name='comehere'),
url(r'^$', 'django.views.generic.simple.redirect_to',
{'url': reverse_lazy('comehere')}, name='root')
)

( Django 1.1.1 )

    • Aaron C. de Bruyn
    • December 14th, 2009

    Awesome! Exactly what I was looking for.

    • gentlestone
    • January 22nd, 2010

    It doesn’t work …

    Lazy object returned unexpected type.

    Request Method: GET
    Request URL: http://127.0.0.1:8000/odhlasenie/
    Exception Type: TypeError
    Exception Value:

    Lazy object returned unexpected type.

    Exception Location: /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/utils/functional.py in __wrapper__, line 192
    Python Executable: /Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python
    Python Version: 2.6.3

    • Andrin
    • February 12th, 2010

    @gentlestone

    hmm… try substituting
    reverse_lazy = lazy(reverse, unicode)
    with
    reverse_lazy = lazy(reverse, str)

  1. No trackbacks yet.