使用URL反转和参数的urls.py重定向——有更简单的方法吗?

4 投票
2 回答
541 浏览
提问于 2025-04-16 19:37

我有两类实体,现在我想从中选择一些组合,定义的URL格式是这样的:

url(r"^category1/(?P<category1>([0123456789]+,?)+)/category2(?P<category2>([0123456789]+,?)+)/$", view, {}, name="cross")

所以像 /category1/1,2,3,4/category2/5,6,7,8/ 这样的URL是有效的。

现在我对这些数据引入了几个视图,所以现在我有了像 /category1/1,2,3,4/category2/5,6,7,8/view1//category1/1,2,3,4/category2/5,6,7,8/view2/ 这样的URL。我想把“旧”的URL重定向到 view1。我找到的最简单的方法是:

url(r"^category1/(?P<category1>([0123456789]+,?)+)/category2(?P<category2>([0123456789]+,?)+)/$",
    redirect_to, {
    'url': lazy(lambda: reverse(
        'cross_view1',
        kwargs={
            'category1': '111111',
            'category2': '222222',
        }
     ).replace('111111', '%(category1)s') \
      .replace('222222', '%(category2)s'), str)(),
     name="cross"}

这里的关键是我想在URL中重用我匹配到的部分,但是我不能把它们作为参数传给 redirect_to,因为那样它们不会被替换。而且我也不能直接把格式放在URL中,因为它必须符合我的正则表达式(用逗号分隔的数字ID)。所以我引入了一些唯一的ID(在这个例子中是111111和222222),然后再进行替换。

显然,这种做法感觉、看起来、闻起来和尝起来都很不优雅。除了引入一个额外的视图并完全跳过 redirect_to,有没有更好的方法呢?

2 个回答

0

简单说一下,在你的正则表达式中,可以用 [0-9] 来代替 [0123456789]。

1

这里有几种选择。你可以使用RedirectView,但我发现它无法反向处理网址,因为它似乎在urlpatterns加载之前就运行了。你可以这样使用它,根据你的项目进行调整:

from django.views.generic import RedirectView

把这个添加到你的urlpatterns里:

url(r'^(?P<location_id>\d+)/$', RedirectView.as_view(url='/statistics/dailyreport/%(location_id)s/')),

使用LAMBDA:这在大多数django版本中应该都能用,我是在1.6.5版本中使用的:

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
urlpatterns = patterns('',
    ....
    url(r'^(?P<location_id>\d+)/$', lambda x, location_id: HttpResponseRedirect(reverse('dailyreport_location', args=[location_id])), name='location_stats_redirect'),
    ....
)

撰写回答