在Django中使用正则表达式动态重定向页面?

2 投票
3 回答
1489 浏览
提问于 2025-04-17 17:20

我在使用Django的时候遇到了一个关于 url.py 的问题。

在我的应用里,有很多类似这样的链接:

aaa-2011-bbb
aaa-2011

我想把这些链接重定向到一个新的链接,去掉年份。所以我需要把年份从链接中去掉。这可能吗?

我现在只有像这样的静态映射:

(r'^aaa-\d{4}-bbb/$', redirect_to, {'url': '/aaa-bbb/'}),

但是我不想为每一个带年份的链接都写一个规则。

3 个回答

0

还有一种方法可以用更少的代码实现相同的功能:

(r'^(?P<aaa>\w+)-\d{4}-(?P<bbb>\w+)/$', RedirectView.as_view(url='%(aaa)s-%(bbb)s')),
2

我会创建一个新的类,继承自RedirectView,用它来实现动态重定向。

urls.py文件中,内容大概是这样的:

(r'^(?P<aaa>\w+)-\d{4}-(?P<bbb>\w+)/$', MyRedirectView.as_view()),

然后在views.py文件中:

from django.views.generic.base import RedirectView

class MyRedirectView(RedirectView):
    permanent = False
    query_string = True

    def get_redirect_url(self, aaa, bbb):
        return '%s-%s' % (aaa, bbb)

这个方法会从urls.py中获取**kwargs里的aaabbb(假设它们是字符串,并且来自你描述的重定向网址),然后返回一个重定向的网址,格式是'%s-%s' % (aaa, bbb)

1

正如@danodonovan提到的,RedirectView 是实现这个功能的最佳方法。

不过,为了避免不必要的重复,我建议如下:

# urls.py
(r"^([^/]*?(19|20)\d{2}[^/]*?)/?$", RemoveYearRedirect.as_view()),

# views.py
from django.views.generic.base import RedirectView
import re

class RemoveYearRedirect(RedirectView):
    query_string = True

    def get_redirect_url(self, **kwargs):
        """
        This has been overriden to remove any year from 1900 to 2099 from the URL
        """
        url = re.sub("(19|20)\d{2}", "", self.args[0])
        return "/" + re.sub("-+", "-", url).strip("-")

这个方法适用于以下网址:

  • /testing-2012-foo --> /testing-foo
  • /2000-never-happened --> /never-happened
  • /movies-from-1960 --> /movies-from

撰写回答