I have a couple problems understanding how redirect or rather reverse really work.
In the main urls.py I have:
from django.conf.urls import patterns, include, url
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
url(r'^$', redirect_to, {'url': '/monitor/'}),
url(r'^monitor/', include('monitor.urls')),
)
and in monitors.urls I have:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('monitor.views',
(r'^$', 'index'),
(r'^abc/(?P<id>.*$)', 'abc'),
)
When you call /monitor I want to redirect it to /monitor/abc so I did:
def index(request):
return redirect("abc")
def abc(render, id=None):
return render_to_response("monitor/list.htmld", {})
But I got an NoReverseMatch exception. But when I do:
def index(request):
return redirect("abc/")
then it suddenly works.
I cannot fully understand why. Why did reverse fail with abc but not with abc/? And how does reverse know that the redirect should include monitor/ as well? What if I had in the main urls.py another app called xyz which also has a abc view?
Because it interpreted it as a view name (and you indeed have a view named
'abc', see yourmonitor.urlsfile). This means Django will callreverseto compute the URL. The valueabc/is interpreted as an actual URL which means Django won’t callreverseto determine the URL.This also explains why
reversefailed: the view with nameabcalso requires an argument calledid. Otherwise Django won’t be able to lookup the URL as there is no view calledabcwithout parameters.Based on the documentation you should be able to reverse the URL using:
where
...is the value of theidparameter.That is because it knows what URLs are available and 1) it knows where the view called
abcis defined and 2) it knows thatmonitors.urlsis included withmonitor/in front.In that case you have to use namespaces.