usar examples english documentacion bootstrap python django django-templates mobile-website django-middleware

python - examples - Cambiar las plantillas de Django en función del usuario-agente



documentacion de django (10)

He hecho un sitio de Django, pero he bebido Koolaid y quiero hacer una versión de iPhone . Después de pensarlo mucho, he encontrado dos opciones:

  1. Cree un sitio completo, como i.xxxx.com. Átelo en la misma base de datos usando el framework de sitios de Django.
  2. Busque un momento de middleware que lea el user-agent y cambie dinámicamente los directorios de plantilla.

Sin embargo, preferiría la opción n. ° 2; Tengo algunas reservas, principalmente porque la documentación de Django desalienta el cambio de configuración sobre la marcha . Encontré un fragmento que haría lo que quisiera. Mi principal problema es que sea lo más transparente posible, me gustaría que sea automático y transparente para el usuario.

¿Alguien más ha tenido el mismo problema? ¿Alguien querría compartir acerca de cómo abordaron la creación de versiones de IPhone de los sitios de Django?

Actualizar

Fui con una combinación de middleware y ajustar la llamada a la plantilla.

Para el middleware, utilicé minidetector . Me gusta porque detecta una plétora de usuarios móviles. Todo lo que tengo que hacer es verificar request.mobile en mis vistas.

Para el cambio de llamada de la plantilla:

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

Lo uso para cualquier vista que sé que tengo ambas versiones.

QUE HACER:

  • Descubre cómo acceder a request.mobile en una versión extendida de render_to_response para no tener que usar check_mobile (''template_name.html'')
  • Usar el respaldo automágicamente anterior a la plantilla normal si no existe una versión móvil.

¿Qué hay de redirigir al usuario a i.xxx.com después de analizar su UA en algún middleware? Dudo mucho que a los usuarios de dispositivos móviles les importe cómo se ven las URL, aún así pueden acceder a su sitio usando la URL principal.


Deberías echarle un vistazo al código fuente django-mobileadmin , que resolvió exactamente este problema.


Detecta el agente de usuario en middleware, cambia los enlaces de URL, ¡aprovecha!

¿Cómo? Los objetos de solicitud de Django tienen un atributo .urlconf, que se puede establecer mediante middleware.

De django docs:

Django determina el módulo raíz URLconf para usar. Normalmente, este es el valor de la configuración ROOT_URLCONF, pero si el objeto HttpRequest entrante tiene un atributo llamado urlconf (establecido por el proceso de solicitud de middleware), su valor se usará en lugar de la configuración ROOT_URLCONF.

  1. En yourproj / middlware.py, escriba una clase que verifique la cadena 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. No olvides agregar esto a MIDDLEWARE_CLASSES en settings.py:

    MIDDLEWARE_CLASSES= [... ''yourproj.middleware.MobileMiddleware'', ...]

  3. Crea un urlconf móvil, yourproj / mobile_urls.py:

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


El mejor escenario posible: use minidetector para agregar la información adicional a la solicitud, luego use el contexto de solicitud incorporado de django para pasarlo a sus plantillas como tal

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

luego en su plantilla puede introducir cosas como:

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


En lugar de cambiar dinámicamente los directorios de plantillas, podría modificar la solicitud y agregar un valor que le permita saber si el usuario tiene un iPhone o no. A continuación, ajuste render_to_response (o lo que sea que esté utilizando para crear objetos HttpResponse) para obtener la versión de iphone de la plantilla en lugar de la versión html estándar si utilizan un iphone.





Otra forma sería crear su propio cargador de plantillas que cargue plantillas específicas para el agente de usuario. Esta es una técnica bastante genérica y puede usarse para determinar dinámicamente qué plantilla debe cargarse dependiendo de otros factores también, como el idioma solicitado (buen compañero de la maquinaria Django i18n existente).

Django Book tiene una sección sobre este tema .


Una solución simple es crear un contenedor alrededor de django.shortcuts.render . Puse el mío en una biblioteca de utils en la raíz de mi aplicación. El contenedor funciona al representar automáticamente las plantillas en una carpeta "móvil" o "de escritorio".

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

En view :

from utils.shortcuts import my_render def home(request): return my_render(request, ''home.html'')