[英]Change Django Templates Based on User-Agent
我已经创建了一个 Django 站点,但是我喝了 Koolaid 并且我想创建一个iPhone版本。 经过深思熟虑,我想出了两个选择:
然而,我真的更喜欢选项#2; 我有一些保留意见,主要是因为 Django 文档不鼓励即时更改设置。 我找到了一个可以做我想做的事情的片段。 我的主要问题是让它尽可能无缝,我希望它对用户来说是自动的和透明的。
有没有其他人遇到过同样的问题? 有没有人愿意分享他们是如何制作 Django 网站的 iPhone 版本的?
更新
我结合了中间件和调整模板调用。
对于中间件,我使用了minidetector 。 我喜欢它,因为它检测到大量的移动用户代理。 我所要做的就是在我的视图中检查 request.mobile。
对于模板调用调整:
def check_mobile(request, template_name):
if request.mobile:
return 'mobile-%s'%template_name
return template_name
我将它用于我知道我有两个版本的任何视图。
去做:
您可以修改请求并添加一个值,让您的视图知道用户是否在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'/?$', 'mobile.index'), ...)
本文可能很有用: 在15分钟内在Django中构建一个移动和桌面友好的应用程序
我正在开发djangobile,一个django移动扩展程序: http : //code.google.com/p/djangobile/
你应该看看django-mobileadmin源代码,它解决了这个问题。
有一篇很好的文章解释了如何通过不同的模板呈现相同的数据http://www.postneo.com/2006/07/26/acknowledging-the-mobile-web-with-django
您仍然需要自动将用户重定向到移动网站,这可以使用多种方法完成(您的check_mobile技巧也可以)
在一些中间件中解析他的UA后,如何将用户重定向到i.xxx.com? 我非常怀疑移动用户是否关注网址的样子,他们仍然可以使用主网址访问您的网站。
最好的方案:使用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')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.