Mobile端末はあっち行けくん。

 諸事情あって大っぴらには言っていませんけども、一応このページにもモバイル用、というかスマートフォン向けのページが用意してあって、各種それっぽい端末の類いでアクセスすると自動的にリダイレクトされて違うURLで表示されます。今時のスマホのブラウザは基本的にWebKit系であるだろうから共通という事にしていても表示上の問題はあまりなかったのですけど、小さく表示されて見にくいだろうなぁというのがありましたし、何よりやってみたかったからとか。

 最初から全てのURLに対応できればよかったのですけど、例の小出し戦略じゃないと身体と気持ちが続かない事情がありましてちょっとずつ対応させたりしました。ので、とりあえず想定する端末ならあっち行けするdecoratorを書いて、モバイルに対応するURLがあるviewだけをデコレートしてました。


import re

def redirect_smart_phone(func):
    def inner(*args, **kwargs):
        if 'HTTP_USER_AGENT' in args[0].META and \
                re.search('iPod|iPhone|Android|BlackBerry|Windows Phone|Symbian',
                          args[0].META['HTTP_USER_AGENT']):
            return redirect(args[0].path.replace('/blog/', '/blog/mobile/'))
        return func(*args, **kwargs)
    return inner

 /blogの後に/mobileが挟まるとそれはモバイル用というURL体系を採用してます。

 そして、全てのURLに対応できたところで、同じ事をするmiddlewareを書いてそちらへ切り替え。

 Django | Middleware | Django documentation
 src/reiare/blog/middleware.py at develop from tactactad/reiare - GitHub


import re

from django.shortcuts import redirect

class RedirectSmartPhoneMiddleware(object):
    def process_request(self, request):
        if request.META.has_key('HTTP_USER_AGENT') and \
                re.search('iPod|iPhone|Android|BlackBerry|Windows Phone|Symbian|Nintendo 3DS',
                          request.META['HTTP_USER_AGENT']) and \
                not re.match('/blog/mobile', request.path):
            return redirect(request.path.replace('/blog/', '/blog/mobile/', 1))
        else:
            return None

 middlewareはリクエストされてからレスポンスを返すまでの間の適当な位置に処理を挟む事ができますし、また複数のmiddlewareがある場合にはその実行順も影響してきます。今回はリクエストされた時点でやっつけて仕舞えばいいので、process_requestメソッドを実装、かつCommonMiddlewareの次に実行させるようにしてみました。

 ちなみに、iPadさんはそれなりに広い画面をお持ちですので対象外です。ニンテンドー3DSさんはWebKit系ブラウザなので対象内です。しかし、この判定方法だとAndorid系タブレットを対象外にできないのですよねぇ……。まぁ、いいか、オレ持ってないし。