Ian Lewis
Ian Lewis is a web developer living in Tokyo Japan. His current interests are in Django, python, alternative databases and rapid web application development. About Me...
  • Django redirect_to はnon-ascii URLに対応してない

    Django は一般的なリダイレクトするビューを django.views.generic.simple.redirect_to に用意していますけど、unicodeのキーワードがあれば、動かないのが最近見つけた。

    Djangoプロジェクトのurls.pyでこういう風にURLの設定を書けます。

    from django.conf.urls.defaults import *
    
    urlpatterns = patterns('django.views.generic.simple',
        url(r'^jp/(?P<tag_name>.+)\;', 'redirect_to', {'url': '/jp/tag/%(tag_name)s'}),
    )
    

    そうした場合、redirect_to は tag_nameに入ったデータをリダイレクト先にURLに入れてくれます。が、そのデータはasciiでない場合、redirect_to の中にtag_nameのデータに入れたURLを urlquoteに特に渡すなど、特に何もしないで、HttpResponseRedirectに渡す。redirect_toはDjango 1.1でこの通り

    def redirect_to(request, url, permanent=True, **kwargs):
        """
        Redirect to a given URL.
    
        The given url may contain dict-style string formatting, which will be
        interpolated against the params in the URL.  For example, to redirect from
        ``/foo/<id>/`` to ``/bar/<id>/``, you could use the following URLconf::
    
            urlpatterns = patterns('',
                ('^foo/(?P<id>\d+)/$', 'django.views.generic.simple.redirect_to', {'url' : '/bar/%(id)s/'}),
            )
    
        If the given url is ``None``, a HttpResponseGone (410) will be issued.
    
        If the ``permanent`` argument is False, then the response will have a 302
        HTTP status code. Otherwise, the status code will be 301.
        """
        if url is not None:
            klass = permanent and HttpResponsePermanentRedirect or HttpResponseRedirect
            return klass(url % kwargs)
        else:
            return HttpResponseGone()
    

    最終的に、この問題が起こる時に、このエラーが出る。

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 8-11: ordinal not in
      range(128), HTTP response headers must be in US-ASCII format
    

    実際は下バグが既にあって、HttpResponseRedirectの中で、asciiでないURLをちゃんとエンコードするはず。

    #11522 Crash on redirect to a relative URL if request.path is unicode

    Send feedback このエントリーを含むはてなブックマーク はてなブックマーク - Django redirect_to はnon-ascii URLに対応してない