diadia

興味があることをやってみる。自分のメモを残しておきます。

django:PCとスマホで表示を変えたい

ユーザーのデバイスによって表示を変更したい

表示方法としてレスポンシブデザインが可能なBootstrapを利用してきた。しかしレスポンシブデザインでは納得いく表現ができなかった。
バイスによって異なるテンプレートを使い分けれればより良くなると思われる。実現できるか調査し実装できれば実装してみたい。

ユーザーのデバイスはuser-agentsを利用して捕捉することができるようだ。
https://pypi.org/project/user-agents/
その他にdjango-user-agentsなるものもあった。これも同じことが実現できそうか?
https://pypi.org/project/django-user-agents/
そもそも標準ライブラリのplatformを使えば対処できるのでは?という疑問も出てくる。何か分かったら更新する。

platformを使う案について

platformではwebアプリにアクセスするユーザーデータ(どんなデバイスを使っているか)を補足することはできない
"実行中プラットフォームの固有情報を参照する"機能を提供するのがplatformなので、これを使ってもdjangoが動くマシンの情報を得るだけになってしまう。だからユーザーのデバイス情報を取得できない。

バイスによってテンプレートを変える

django-user-agentsを使う案

django-user-agentsを使うと手軽にテンプレートをデバイスによって使い分けられるようになった。テンプレートの使い分けはviews.pyでユーザのデバイスの種類を特定し、デバイスの種類によってrenderでテンプレートを使い分ける。

その他に同一のテンプレートにスマホ、PC用の内容を記述する方法もある。この場合はdjango-user-agentsのテンプレートタグである
{% load user_agents %}や{% if request|is_pc %}等を使って実装する。これはデバイスごとに複数のテンプレートを準備するviews.pyのデメリットを解消できる。

下記はviews.pyにdjango-user-agentsを使う方法である。

from django_user_agents.utils import get_user_agent

class ProductListView(View):

    def get(self, request, *args, **kwargs):
        object_list = Product.objects.all()
        context["object_list"] = object_list
        
        user_agent = get_user_agent(request)
        if user_agent.is_mobile:
            return render(request, "products/list_mobile.html", context)
            
        elif user_agent.is_tablet:
            return render(request, "products/list_tablet.html", context)
            
        else:
            return render(request, "products/list_pc.html", context)

django-user-agentsを使うとミドルウェアを通してrequestに属性を付け加えられる。これを利用してユーザーのデバイスを特定することができる。

インストール方法

pip install pyyaml ua-parser user-agents
pip install django-user-agents

場合によっては以下もインストールが必要。

pip install python-memcached

参考:https://stackoverflow.com/questions/41575601/importerror-no-module-named-memcache-django-project

settings.pyの設定項目

INSTALLED_APPS = (
    # Other apps...
    'django_user_agents',
)

# キャッシュを使うとdjango-user-agentsを素早く働かせることができる
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}


# キャッシュを使わない場合はNoneと記述。キャッシュを使う場合は基本的には'default'を使う
USER_AGENTS_CACHE = 'default'

# ミドルウェアにも下記を加える
MIDDLEWARE_CLASSES = (
    # other middlewares...
    'django_user_agents.middleware.UserAgentMiddleware',
)