Django中的相对重定向

3 投票
1 回答
1999 浏览
提问于 2025-04-17 03:11

我现在的应用程序的URL配置是这样的:

from django.conf.urls.defaults import patterns
from django.views.generic.simple import redirect_to

urlpatterns = patterns("myapp.views",
    (r"^$", redirect_to, {"url": "main/"}),
    (r"^(?P<title>.+)/$", "article"),
    ...
)

当我直接使用应用的URL时,这个配置运行得很好。

现在,我想把我的应用的URL放到一个项目的URL配置中,并加上前缀,像这样:

urlpatterns = patterns("",
    (r"^myapp/", include("myapp.urls")),
)

但是这样一来,http://myserver.org/myapp/ 就不会重定向到 http://myserver.org/myapp/main/,而是重定向到 http://myserver.org/main/

我想我明白这是怎么回事:项目的URL模式加上了 "myapp/"。这个前缀会被去掉,留下 "",然后这个空字符串会传给应用的模式。应用并不关心这个去掉的过程,只是重定向到 main/而Django把它理解为 /main/,这对更深层次的嵌套URL就不管用了(见下面的编辑)。

我该怎么告诉Django重定向到相对于应用前缀的URL呢?


编辑:错误!

啊!上面的代码其实没问题,但我的浏览器缓存了之前的永久重定向到 "/main/"。我清除了缓存,现在我的新URL "main/"(为了防止缓存,现在是临时的)运行得很好。抱歉!

不过我意识到,如果我想从更深层次的嵌套中访问相对于应用根目录的URL,给出一个答案会很有帮助:"relative/" 可能适用于 http://myserver.org/myapp/foo/,但不适用于 http://myserver.org/myapp/foo/bar/

1 个回答

2

在django 1.4版本中,你可以使用一个叫做 reverse_lazy() 的函数:

from django.core.urlresolvers import reverse_lazy
urlpatterns = patterns("myapp.views",
    (r"^$", redirect_to, {"url": reverse_lazy("myapp_title")}),
    (r"^(?P<title>.+)/$", "article", name="myapp_title"),
    ...
)

reverse_lazy() 会根据你传给它的“名字”参数,找到对应的URL地址。

如果你使用的是早期版本,你就需要写出完整的路径,这样做会违反“不要重复自己”的原则:

(r"^$", redirect_to, {"url": "myapp/title/"}),

撰写回答