Изменение шаблонов Django на основе агента пользователя - PullRequest
40 голосов
/ 03 октября 2008

Я сделал сайт 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

Я использую это для любого представления, которое я знаю, у меня есть обе версии.

TODO:

  • Узнайте, как получить доступ к request.mobile в расширенной версии render_to_response, поэтому мне не нужно использовать check_mobile ('template_name.html')
  • Использование предыдущего автоматического возврата к обычному шаблону, если мобильной версии не существует.

Ответы [ 10 ]

20 голосов
/ 03 октября 2008

Вместо того, чтобы динамически изменять каталоги шаблонов, вы можете изменить запрос и добавить значение, которое позволяет вашему представлению знать, находится ли пользователь на iphone или нет. Затем оберните render_to_response (или то, что вы используете для создания объектов HttpResponse), чтобы получить версию шаблона для iphone вместо стандартной версии html, если они используют iphone.

11 голосов
/ 15 августа 2010

Обнаружение пользовательского агента в промежуточном программном обеспечении, переключение привязок URL, прибыль!

Как? Объекты запроса Django имеют атрибут .urlconf, который может быть установлен промежуточным программным обеспечением.

Из документации Django:

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. Не забудьте добавить это в MIDDLEWARE_CLASSES в settings.py:

    MIDDLEWARE_CLASSES= [...
        'yourproj.middleware.MobileMiddleware',
    ...]
    
  3. Создать мобильный urlconf, yourproj / mobile_urls.py:

    urlpatterns=patterns('',('r'/?$', 'mobile.index'), ...)
    
4 голосов
/ 11 января 2009
3 голосов
/ 19 октября 2008

Я разрабатываю djangobile, мобильное расширение для django: http://code.google.com/p/djangobile/

2 голосов
/ 18 ноября 2008

Есть хорошая статья, которая объясняет, как визуализировать одни и те же данные с помощью разных шаблонов. http://www.postneo.com/2006/07/26/acknowledging-the-mobile-web-with-django

Однако вам все равно нужно автоматически перенаправить пользователя на мобильный сайт, и это можно сделать несколькими способами (ваш трюк check_mobile тоже будет работать)

2 голосов
/ 16 октября 2008

Другим способом было бы создание собственного загрузчика шаблонов, который загружает шаблоны, специфичные для пользовательского агента. Это довольно общий метод, и его можно использовать для динамического определения того, какой шаблон должен быть загружен, в зависимости от других факторов, таких как запрашиваемый язык (хороший компаньон для существующего механизма Django i18n).

Книга Джанго имеет раздел на эту тему .

2 голосов
/ 10 октября 2008

Вам следует взглянуть на исходный код django-mobileadmin , который решил именно эту проблему.

1 голос
/ 11 ноября 2010

наилучший возможный сценарий: используйте 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>
1 голос
/ 03 октября 2008

Как насчет перенаправления пользователя на i.xxx.com после анализа его UA в некотором промежуточном программном обеспечении? Я очень сомневаюсь, что мобильным пользователям все равно, как выглядит URL, однако они могут получить доступ к вашему сайту с помощью основного URL.

0 голосов
/ 25 января 2013

Простое решение - создать оболочку вокруг django.shortcuts.render. Я положил свою в utils библиотеку в корень моего приложения. Оболочка работает, автоматически отображая шаблоны в папке «mobile» или «desktop»

В 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)

In view:

from utils.shortcuts import my_render

def home(request):    return my_render(request, 'home.html')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...