Изменение шаблонов Django На основе пользовательского агента
-
03-07-2019 - |
Вопрос
Я создал сайт на Django, но я выпил Koolaid и хочу создать iPhone версия.После долгих размышлений я пришел к двум вариантам:
- Создайте совершенно другой сайт, например i.xxxx.com.Привяжите его к той же базе данных, используя платформу сайтов Django.
- Найдите некоторое время промежуточного программного обеспечения, которое считывает пользовательский агент и динамически изменяет каталоги шаблонов.
Однако я бы действительно предпочел вариант № 2;У меня есть некоторые оговорки, главным образом потому, что документация Django препятствует изменению настроек на лету.Я нашел фрагмент текста это сделало бы то, что я хотел.Моя главная проблема заключается в том, чтобы сделать его как можно более плавным, я бы хотел, чтобы он был автоматическим и прозрачным для пользователя.
Кто-нибудь еще сталкивался с такой же проблемой?Не хотел бы кто-нибудь поделиться тем, как они взялись за создание iPhone-версий сайтов Django?
Обновить
Я выбрал комбинацию промежуточного программного обеспечения и настройки вызова шаблона.
Для промежуточного программного обеспечения я использовал минидетектор.Мне это нравится, потому что оно обнаруживает изобилие мобильных пользовательских агентов.Все, что мне нужно сделать, это проверить request.mobile в моих представлениях.
Для настройки шаблона вызовите tweak:
def check_mobile(request, template_name):
if request.mobile:
return 'mobile-%s'%template_name
return template_name
Я использую это для любого представления, о котором я знаю, что у меня есть обе версии.
TODO:
- Выясните, как получить доступ запрос.мобильный в расширенной версии render_to_response, поэтому мне не нужно использовать check_mobile('template_name.html')
- Используя предыдущий, автоматически возвращайтесь к обычному шаблону, если мобильной версии не существует.
Решение
Вместо динамического изменения каталогов шаблонов вы могли бы изменить запрос и добавить значение, которое позволяет вашему представлению узнать, находится ли пользователь на iphone или нет.Затем оберните render_to_response (или что бы вы ни использовали для создания объектов HttpResponse), чтобы использовать версию шаблона для iphone вместо стандартной версии html, если они используют iphone.
Другие советы
Обнаруживайте пользовательский агент в промежуточном программном обеспечении, переключайте привязки URL-адресов, получайте прибыль!
Каким образом?Объекты запроса Django имеют атрибут .urlconf, который может быть установлен промежуточным программным обеспечением.
Из документов django:
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"
Не забудьте добавить это в MIDDLEWARE_CLASSES в settings.py:
MIDDLEWARE_CLASSES= [... 'yourproj.middleware.MobileMiddleware', ...]
Создайте мобильный urlconf, yourproj/mobile_urls.py:
urlpatterns=patterns('',('r'/?$', 'mobile.index'), ...)
Эта статья может быть полезной: Создайте мобильное и настольное приложение на Django за 15 минут
Я разрабатываю djangobile, мобильное расширение django: http://code.google.com/p/djangobile/
Вам следует взглянуть на django-мобильный администратор исходный код, который решил именно эту проблему.
Другим способом было бы создать свой собственный загрузчик шаблонов, который загружает шаблоны, специфичные для user agent.Это довольно общий метод, и его можно использовать для динамического определения того, какой шаблон должен быть загружен, в зависимости от других факторов, таких как запрашиваемый язык (хороший компаньон для существующего оборудования Django i18n).
В книге Django есть раздел по этому вопросу.
Есть хорошая статья, в которой объясняется, как отображать одни и те же данные с помощью разных шаблонов http://www.postneo.com/2006/07/26/acknowledging-the-mobile-web-with-django
Однако вам все равно нужно автоматически перенаправлять пользователя на мобильный сайт, и это можно сделать с помощью нескольких методов (ваш трюк с check_mobile тоже сработает)
Как насчет перенаправления пользователя на i.xxx.com после разбора его UA в каком-нибудь промежуточном программном обеспечении?Я сильно сомневаюсь, что мобильных пользователей волнует, как выглядит URL-адрес, тем не менее они могут получить доступ к вашему сайту по основному URL.
наилучший возможный сценарий:используйте 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
библиотека в корневом каталоге моего приложения.Оболочка работает путем автоматического рендеринга шаблонов либо в папке "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)
В view
:
from utils.shortcuts import my_render def home(request): return my_render(request, 'home.html')