通常在URLconf中重定向是这样的:
from django.views.generic.simple import redirect_to
urlpatterns = patterns('django.views.generic.simple',
(ur'^old/$', 'redirect_to', {'url': ur'/new/', 'permanent': False}),
)
此外,我需要GET查询才能保持原位(domain.com/old/?p=0
=> domain.com/new/?p=0
)。
我是这样做的:
from django.views.generic.simple import redirect_to
urlpatterns = patterns('django.views.generic.simple',
(ur'^old/$', lambda request, url, permanent: redirect_to(request = request, url = url + (request.META['QUERY_STRING'] and ('?'+request.META['QUERY_STRING'])), permanent = permanent), {'url': ur'/new/', 'permanent': False}),
)
它运作得很好。
使用命名的正则表达式组:
from django.views.generic.simple import redirect_to
urlpatterns = patterns('django.views.generic.simple',
(ur'^old/(?P<id>\d+)/$', lambda request, url, permanent, id: redirect_to(request = request, url = url + (request.META['QUERY_STRING'] and ('?'+request.META['QUERY_STRING'])), permanent = permanent, id = id), {'url': ur'/new/%(id)s/', 'permanent': False}),
)
经过测试并运作良好。
我卡住的地方:如果查询值中有Unicode字符,例如?city=Orléans
,它会遇到:
Exception Type: TypeError
Exception Value: not enough arguments for format string
Exception Location: /usr/local/lib/python2.5/site-packages/django/views/generic/simple.py in redirect_to, line 39
答案 0 :(得分:0)
所以redirect_to
试图解析这个'%'。
解决方案是解码查询字符串以消除'%',例如使用urllib2.unquote
所以最终的代码是:
from django.views.generic.simple import redirect_to
from urllib2 import unquote
urlpatterns = patterns('django.views.generic.simple',
(ur'^old/(?P<id>\d+)/$', lambda request, url, permanent, id: redirect_to(request = request, url = url + (request.META['QUERY_STRING'] and ('?'+unquote(request.META['QUERY_STRING']).decode("utf8"))), permanent = permanent, id = id), {'url': ur'/new/%(id)s/', 'permanent': False}),
)
有人能让它看起来更好吗? :)
<强>更新强>
django.views.generic.simple.redirect_to中提到了另一种解决方案:
因为关键字插值总是完成(即使没有传入参数),URL中的任何“%”字符都必须写为“%%”,以便Python将它们转换为输出上的单个百分号。 / p>
<强>更新强>
由于Django 1.3有内置的基于类的视图RedirectView,它可以毫不费力地完成所有工作。