Pregunta

He creado un sitio de Django, pero he bebido el Koolaid y quiero hacer una versión de IPhone . Después de pensar mucho, he encontrado dos opciones:

  1. Crea un sitio completamente diferente, como i.xxxx.com. Átelo en la misma base de datos utilizando el marco de sitios de Django.
  2. Encuentre un tiempo de middleware que lea el agente de usuario y cambie los directorios de la plantilla dinámicamente.

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

¿Alguien más ha encontrado el mismo problema? ¿Le importaría a alguien compartir cómo ha abordado la creación de versiones para iPhone de los sitios de Django?

Actualizar

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

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

Para la plantilla llamada tweak:

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

Uso esto para cualquier vista que sepa que tengo ambas versiones.

TODO:

  • Averigüe cómo acceder a request.mobile en una versión extendida de render_to_response para que no tenga que usar check_mobile ('template_name.html')
  • Si no existe una versión móvil, se utiliza el respaldo automático automágicamente de la plantilla normal.
¿Fue útil?

Solución

En lugar de cambiar dinámicamente los directorios de plantillas, puede modificar la solicitud y agregar un valor que le permita a su vista saber si el usuario está en un iPhone o no. Luego envuelva render_to_response (o lo que esté usando para crear objetos HttpResponse) para obtener la versión de la plantilla para el iPhone en lugar de la versión html estándar si están usando un iPhone.

Otros consejos

¡Detecte el agente de usuario en middleware, cambie los enlaces de url, gane!

¿Cómo? Los objetos de solicitud de Django tienen un atributo .urlconf, que puede ser configurado por middleware.

De los documentos de django:

  

Django determina la raíz URLconf   Módulo a utilizar. Normalmente, esta es la   valor de la configuración ROOT_URLCONF, pero   si el objeto HttpRequest entrante tiene   un atributo llamado urlconf (establecido por   procesamiento de solicitud de middleware), su   valor será utilizado en lugar de la   Configuración de ROOT_URLCONF.

  1. En yourproj / middlware.py, escribe 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 una urlconf móvil, yourproj / mobile_urls.py:

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

Estoy desarrollando djangobile, una extensión móvil de django: http://code.google.com / p / djangobile /

Debería echar un vistazo al django-mobileadmin , que es el código fuente. Resuelto exactamente este problema.

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 se puede usar para determinar de forma dinámica qué plantilla se debe cargar dependiendo de otros factores, como el idioma solicitado (buen compañero de la maquinaria Django i18n existente).

Django Book tiene una sobre este tema .

Hay un buen artículo que explica cómo representar los mismos datos con diferentes plantillas http://www.postneo.com/ 2006/07/26 / acuse de recibo del móvil-web-con-django

Sin embargo, aún debe redireccionar automáticamente al usuario al sitio móvil y esto puede hacerse utilizando varios métodos (su truco check_mobile también funcionará)

¿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 móviles les importe cómo se ve la url, aún así pueden acceder a su sitio usando la url principal.

el mejor escenario posible: use el 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 así

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

entonces en tu plantilla puedes 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>

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

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 la vista :

from utils.shortcuts import my_render

def home(request):    return my_render(request, 'home.html')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top