我正在制作一个重要的新闻发布平台。基本上用django从零开始重建所有东西。现在我们已经准备好启动了,我需要处理遗留的URL重定向。考虑到我必须处理成千上万的遗留网址,最好的方法是什么?
逻辑应该像这样工作:如果匹配的现有网址/视图都没有通过遗留重定向网址模式/视图运行该网址,以查看它是否可以在返回404错误之前提供一些重定向到新网址。
我该怎么做?
答案 0 :(得分:1)
很棒,通过使用自定义中间件实现了这一点:
from django.http import Http404
from legacy.urls import urlpatterns
class LegacyURLsMiddleware(object):
def process_response(self, request, response):
if response.status_code != 404:
return response
for resolver in urlpatterns:
try:
match = resolver.resolve(request.path[1:])
if match:
return match.func(request, *match.args, **match.kwargs)
except Http404:
pass
return response
只需将此中间件添加为MIDDLEWARE_CLASSES列表中的最后一个中间件即可。然后在遗留应用程序中使用urls.py文件来声明将处理永久重定向的旧URL和视图。请勿将旧网址包含在主网址结构中。这个中间件为你做了,但有点不同。
答案 1 :(得分:0)
您可能想要创建一个后备视图,该视图将尝试处理您的模式未处理的任何网址。我看到两个选择。
只需创建一个“默认”模式。这种模式很重要 是你的urlpatterns中的最后一个!
你的urls.py中的:
urlpatterns = patterns(
'',
# all your patterns
url(r'^.+/', 'app.views.fallback')
)
在你的views.py中:
from django.http.response import HttpResponseRedirect, Http404
def fallback(request):
if is_legacy(request.path):
return HttpResponseRedirect(convert(request.path))
raise Http404
创建自定义http 404处理程序。
你的urls.py中的:
handler404 = 'app.views.fallback'
你的views.py中的
from django.http.response import HttpResponseRedirect
from django.views.defaults import page_not_found
def fallback(request):
if is_legacy(request.path):
return HttpResponseRedirect(convert(request.path))
return page_not_found(request)
它似乎是一个更好的解决方案,但它只有在您将DEBUG设置为False并提供自定义404模板时才有效。
答案 2 :(得分:0)
使用雅各布的django-multiurl。有一天django ticket可以解决这个问题,但是现在django-multiurl
效果非常好。
在:
# urls.py
urlpatterns = patterns('',
url('/app/(\w+)/$', app.views.people),
url('/app/(\w+)/$', app.views.place), # <-- Never matches
)
后:
# urls.py
from multiurl import multiurl, ContinueResolving
from django.http import Http404
urlpatterns = patterns('', multiurl(
url('/app/(\w+)/$', app.views.people), # <-- Tried 1st
url('/app/(\w+)/$', app.views.place), # <-- Tried 2nd (only if 1st raised Http404)
catch=(Http404, ContinueResolving)
))