User-Agentに基づいてDjangoテンプレートを変更する
-
03-07-2019 - |
質問
Djangoサイトを作成しましたが、Koolaidを飲んだので、 IPhone バージョンを作成したいと思います。よく考えてから、2つのオプションを考え出しました。
- i.xxxx.comなど、他のサイト全体を作成します。 Djangoのサイトフレームワークを使用して、同じデータベースに関連付けます。
- ユーザーエージェントを読み取り、テンプレートディレクトリを動的に変更するミドルウェアを少し見つけます。
ただし、オプション2を本当に好むでしょう。主にDjangoのドキュメント設定をその場で変更しないように 。私が望むことをするスニペットを見つけました。私の主な問題は、それを可能な限りシームレスにすることです。ユーザーに自動で透過的であるようにしたいです。
同じ問題に遭遇した人はいますか?誰かがDjangoサイトのIPhoneバージョンの作成に取り組んだ方法について共有したいですか?
更新
ミドルウェアとテンプレート呼び出しの調整の組み合わせを使用しました。
ミドルウェアには、 minidetector を使用しました。モバイルユーザーエージェントの過剰なを検出するため、気に入っています。私がしなければならないのは、自分のビューでrequest.mobileを確認することだけです。
テンプレート呼び出しの調整:
def check_mobile(request, template_name):
if request.mobile:
return 'mobile-%s'%template_name
return template_name
両方のバージョンがあることがわかっているビューにはこれを使用します。
TODO:
- render_to_responseの拡張バージョンで request.mobile にアクセスする方法を理解し、check_mobile( 'template_name.html')を使用する必要がないようにします
- モバイルバージョンが存在しない場合は、以前のテンプレートを自動的に通常のテンプレートにフォールバックします。
解決
テンプレートディレクトリを動的に変更するのではなく、リクエストを変更して、ユーザーがiPhoneを使用しているかどうかをビューに知らせる値を追加できます。次に、render_to_response(またはHttpResponseオブジェクトの作成に使用しているもの)をラップして、iphoneを使用している場合、標準のhtmlバージョンではなくiphoneバージョンのテンプレートを取得します。
他のヒント
ミドルウェアでユーザーエージェントを検出し、URLバインディングを切り替えてください!
どのように? Djangoリクエストオブジェクトには.urlconf属性があり、ミドルウェアで設定できます。
django docsから:
DjangoはルートURLconfを決定します 使用するモジュール。通常、これは ROOT_URLCONF設定の値ですが、 着信HttpRequestオブジェクトが持っている場合 urlconfと呼ばれる属性(によって設定 ミドルウェア要求処理)、その の代わりに値が使用されます ROOT_URLCONF設定。
-
yourproj / middlware.pyで、http_user_agent文字列をチェックするクラスを記述します。
import re MOBILE_AGENT_RE=re.compile(r".*(iphone|mobile|androidtouch)",re.IGNORECASE) class MobileMiddleware(object): def process_request(self,request): if MOBILE_AGENT_RE.match(request.META['HTTP_USER_AGENT']): request.urlconf="yourproj.mobile_urls"
-
これをsettings.pyのMIDDLEWARE_CLASSESに追加することを忘れないでください:
MIDDLEWARE_CLASSES= [... 'yourproj.middleware.MobileMiddleware', ...]
-
モバイルurlconf、yourproj / mobile_urls.pyを作成します:
urlpatterns=patterns('',('r'/?
この記事は役に立つかもしれません: 15分でDjangoでモバイルおよびデスクトップフレンドリーなアプリケーションを構築
djangoモバイル拡張機能であるdjangobileを開発しています: http://code.google.com / p / djangobile /
django-mobileadmin のソースコードをご覧ください。まさにこの問題を解決しました。
他の方法は、ユーザーエージェントに固有のテンプレートをロードする独自のテンプレートローダーを作成することです。これは非常に一般的な手法であり、要求された言語(既存のDjango i18n機構の優れたコンパニオン)などの他の要因に応じて、どのテンプレートをロードする必要があるかを動的に決定するために使用できます。
Django Bookには、このテーマに関するセクションがあります。
>異なるテンプレートで同じデータをレンダリングする方法を説明した素晴らしい記事があります http://www.postneo.com/ 2006/07/26 / acknowledging-the-mobile-web-with-django
ただし、ユーザーをモバイルサイトに自動的にリダイレクトする必要はありますが、これはいくつかの方法を使用して実行できます(check_mobileトリックも機能します)
いくつかのミドルウェアでUAを解析した後、ユーザーをi.xxx.comにリダイレクトするのはどうですか?モバイルユーザーはURLの表示方法を気にかけているのに、メインURLを使用してサイトにアクセスできることを非常に疑います。
最良のシナリオ:minidetectorを使用してリクエストに追加情報を追加し、djangoの組み込みリクエストコンテキストを使用してテンプレートに渡します
from django.shortcuts import render_to_response
from django.template import RequestContext
def my_view_on_mobile_and_desktop(request)
.....
render_to_response('regular_template.html',
{'my vars to template':vars},
context_instance=RequestContext(request))
テンプレートに次のようなものを導入できます:
<html>
<head>
{% block head %}
<title>blah</title>
{% if request.mobile %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-mobile.css">
{% else %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-desktop.css">
{% endif %}
</head>
<body>
<div id="navigation">
{% include "_navigation.html" %}
</div>
{% if not request.mobile %}
<div id="sidebar">
<p> sidebar content not fit for mobile </p>
</div>
{% endif %>
<div id="content">
<article>
{% if not request.mobile %}
<aside>
<p> aside content </p>
</aside>
{% endif %}
<p> article content </p>
</aricle>
</div>
</body>
</html>
簡単な解決策は、 django.shortcuts.render
のラッパーを作成することです。私はアプリケーションのルートにある utils
ライブラリに私のものを置きました。ラッパーは、「モバイル」またはまたは「デスクトップ」フォルダ。
utils.shortcuts
で:
from django.shortcuts import render from user_agents import parse def my_render(request, *args, **kwargs): """ An extension of django.shortcuts.render. Appends 'mobile/' or 'desktop/' to a given template location to render the appropriate template for mobile or desktop depends on user_agents python library https://github.com/selwin/python-user-agents """ template_location = args[0] args_list = list(args) ua_string = request.META['HTTP_USER_AGENT'] user_agent = parse(ua_string) if user_agent.is_mobile: args_list[0] = 'mobile/' + template_location args = tuple(args_list) return render(request, *args, **kwargs) else: args_list[0] = 'desktop/' + template_location args = tuple(args_list) return render(request, *args, **kwargs)
view
で:
from utils.shortcuts import my_render def home(request): return my_render(request, 'home.html')