问题
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?
回答1:
Why did reverse fail with 'abc' but not with 'abc/'?
Because it interpreted it as a view name (and you indeed have a view named 'abc', see your monitor.urls file). This means Django will call reverse to compute the URL. The value abc/ is interpreted as an actual URL which means Django won't call reverse to determine the URL.
This also explains why reverse failed: the view with name abc also requires an argument called id. Otherwise Django won't be able to lookup the URL as there is no view called abc without parameters.
Based on the documentation you should be able to reverse the URL using:
redirect("abc", id=...)
where ... is the value of the id parameter.
And how does reverse know that the redirect should include monitor/ as well?
That is because it knows what URLs are available and 1) it knows where the view called abc is defined and 2) it knows that monitors.urls is included with monitor/ in front.
What if I had in the main urls.py another app called "xyz" which also has a "abc" view?
In that case you have to use namespaces.
来源:https://stackoverflow.com/questions/11938458/understanding-django-shortcuts-redirect