我创建了一个Django网站,但我喝了Koolaid,我想制作一个 IPhone 版本。经过深思熟虑之后,我提出了两个选择:
然而,我真的更喜欢选项#2;我有一些保留意见,主要是因为Django文档discourages changing settings on the fly。我找到了snippet,可以按照我的意愿行事。我的主要问题是让它尽可能无缝,我希望它对用户来说是自动化和透明的。
还有其他人遇到同样的问题吗?是否有人愿意分享他们如何解决制作iPhone版Django网站的问题?
更新
我使用了中间件和调整模板调用的组合。
对于中间件,我使用minidetector。我喜欢它,因为它检测到plethora个移动用户代理。我所要做的就是在我的观点中检查request.mobile。
对于模板调用调整:
def check_mobile(request, template_name):
if request.mobile:
return 'mobile-%s'%template_name
return template_name
我将此用于任何我知道我有两个版本的视图。
TODO:
答案 0 :(得分:20)
您可以修改请求并添加一个值,让您的视图知道用户是否在iPhone上,而不是动态更改模板目录。然后包装render_to_response(或用于创建HttpResponse对象的任何内容)以获取模板的iphone版本而不是标准html版本(如果他们使用的是iphone)。
答案 1 :(得分:11)
检测中间件中的用户代理,切换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'), ...)
答案 2 :(得分:4)
答案 3 :(得分:3)
我正在开发djangobile,一个django移动扩展程序:http://code.google.com/p/djangobile/
答案 4 :(得分:2)
您应该查看django-mobileadmin源代码,它解决了这个问题。
答案 5 :(得分:2)
其他方式是创建自己的模板加载器,加载特定于用户代理的模板。这是非常通用的技术,可用于动态确定必须加载哪些模板,这取决于其他因素,如请求的语言(现有Django i18n机器的良好伴侣)。
Django Book有section on this subject。
答案 6 :(得分:2)
有一篇很好的文章解释了如何通过不同的模板呈现相同的数据 http://www.postneo.com/2006/07/26/acknowledging-the-mobile-web-with-django
您仍然需要自动将用户重定向到移动网站,这可以使用多种方法完成(您的check_mobile技巧也可以使用)
答案 7 :(得分:1)
在某些中间件中解析他的UA后,如何将用户重定向到i.xxx.com?我非常怀疑移动用户是否关注网址的样子,他们仍然可以使用主网址访问您的网站。
答案 8 :(得分:1)
最佳方案:使用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>
答案 9 :(得分:0)
一个简单的解决方案是在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')