繁体   English   中英

基于 User-Agent 更改 Django 模板

[英]Change Django Templates Based on User-Agent

我已经创建了一个 Django 站点,但是我喝了 Koolaid 并且我想创建一个iPhone版本。 经过深思熟虑,我想出了两个选择:

  1. 制作一个完整的其他网站,例如 i.xxxx.com。 使用 Django 的站点框架将其绑定到同一个数据库中。
  2. 找一些时间读取用户代理的中间件,并动态更改模板目录。

然而,我真的更喜欢选项#2; 我有一些保留意见,主要是因为 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')
  • 如果不存在移动版本,则使用以前的自动回退到常规模板。

您可以修改请求并添加一个值,让您的视图知道用户是否在iphone上,而不是动态更改模板目录。 然后包装render_to_response(或用于创建HttpResponse对象的任何内容)以获取模板的iphone版本而不是标准html版本(如果他们使用的是iphone)。

检测中间件中的用户代理,切换url绑定,获利!

怎么样? Django请求对象具有.urlconf属性,可以由中间件设置。

来自django docs:

Django确定要使用的根URLconf模块。 通常,这是ROOT_URLCONF设置的值,但如果传入的HttpRequest对象具有名为urlconf的属性(由中间件请求处理设置),则将使用其值代替ROOT_URLCONF设置。

  1. 在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" 
  2. 不要忘记将它添加到settings.py中的MIDDLEWARE_CLASSES:

     MIDDLEWARE_CLASSES= [... 'yourproj.middleware.MobileMiddleware', ...] 
  3. 创建一个移动urlconf,yourproj / mobile_urls.py:

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

我正在开发djangobile,一个django移动扩展程序: 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? 我非常怀疑移动用户是否关注网址的样子,他们仍然可以使用主网址访问您的网站。

最好的方案:使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM