根据用户代理改变Django模板

41 投票
9 回答
19228 浏览
提问于 2025-04-11 09:34

我做了一个Django网站,但我想做一个iPhone版本。经过一番思考,我想出了两个选择:

  1. 做一个完全不同的网站,比如i.xxxx.com。然后用Django的站点框架把它和同一个数据库连接起来。
  2. 找一种中间件,能够读取用户代理(user-agent),并动态改变模板目录。

我更倾向于第二个选项,不过我有一些顾虑,主要是因为Django的文档不鼓励动态改变设置。我找到了一段代码片段,可以实现我想要的功能。我的主要问题是希望这个过程尽可能无缝,让用户感觉不到任何变化。

有没有人遇到过类似的问题?有人愿意分享一下他们是如何制作Django网站的iPhone版本的吗?

更新

我选择了中间件和调整模板调用的组合。

在中间件方面,我使用了minidetector。我喜欢它,因为它可以检测到很多移动设备的用户代理。我的视图中只需要检查request.mobile。

关于模板调用的调整:

 def check_mobile(request, template_name):
     if request.mobile:
         return 'mobile-%s'%template_name
     return template_name

我在任何我知道有两个版本的视图中使用这个。

待办事项:

  • 弄清楚如何在扩展的render_to_response中访问request.mobile,这样我就不需要使用check_mobile('template_name.html')
  • 使用之前的方法,如果没有移动版本,自动回退到常规模板。

9 个回答

3

我正在开发一个叫做djangobile的项目,这是一个Django的移动扩展:http://code.google.com/p/djangobile/

14

在中间件中检测用户代理,切换网址绑定,赚到钱!

怎么做呢?Django的请求对象有一个叫做.urlconf的属性,这个属性可以通过中间件来设置。

根据Django的文档:

Django会确定使用哪个根URL配置模块。通常,这个模块的值是ROOT_URLCONF设置的值,但如果传入的HttpRequest对象有一个叫做urlconf的属性(这个属性是通过中间件处理请求时设置的),那么它的值将会替代ROOT_URLCONF的设置。

  1. 在你的项目目录下的middleware.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"
    
  2. 别忘了在settings.py中把这个类添加到MIDDLEWARE_CLASSES里:

    MIDDLEWARE_CLASSES= [...
        'yourproj.middleware.MobileMiddleware',
    ...]
    
  3. 创建一个移动设备的urlconf,文件名为yourproj/mobile_urls.py:

    urlpatterns=patterns('',('r'/?$', 'mobile.index'), ...)
    
20

与其动态地改变模板目录,不如直接修改请求,添加一个值来告诉你的视图用户是否在使用iPhone。然后,你可以把render_to_response(或者你用来创建HttpResponse对象的其他方法)包裹起来,这样如果用户使用的是iPhone,就能获取到iPhone版本的模板,而不是普通的HTML版本。

撰写回答