Django URLconf:重定向,同时保留URL的查询部分和unicode

时间:2014-01-22 03:26:29

标签: python django unicode

通常在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

1 个答案:

答案 0 :(得分:0)

网址'%-encoding'中的'Orléans'是'Orl%C3%A9ans':URI and IRI handling

所以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,它可以毫不费力地完成所有工作。