Domanda

Ho creato un sito Django, ma ho bevuto Koolaid e voglio fare una versione IPhone . Dopo aver riflettuto a fondo ho escogitato due opzioni:

  1. Crea un altro sito, come i.xxxx.com. Collegalo allo stesso database usando il framework dei siti di Django.
  2. Trova un po 'di tempo per il middleware che legge lo user-agent e modifica dinamicamente le directory dei template.

Preferirei davvero l'opzione n. 2, comunque; Ho delle riserve, principalmente perché la documentazione di Django scoraggia la modifica al volo delle impostazioni . Ho trovato un snippet che farebbe ciò che mi piacerebbe. Il mio problema principale è averlo il più semplice possibile, mi piacerebbe che fosse automagico e trasparente per l'utente.

Qualcun altro ha riscontrato lo stesso problema? Qualcuno vorrebbe condividere su come hanno affrontato la creazione di versioni IPhone dei siti Django?

Aggiorna

Sono andato con una combinazione di middleware e ottimizzando la chiamata del modello.

Per il middleware, ho usato minidetector . Mi piace perché rileva un plethora di user-agent mobili. Tutto quello che devo fare è controllare request.mobile nelle mie visualizzazioni.

Per la modifica del modello di chiamata:

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

Lo uso per qualsiasi vista che so di avere entrambe le versioni.

TODO:

  • Scopri come accedere a request.mobile in una versione estesa di render_to_response, quindi non devo usare check_mobile ('template_name.html')
  • Utilizzo del fallback automagicamente precedente al modello normale se non esiste una versione mobile.
È stato utile?

Soluzione

Anziché modificare dinamicamente le directory dei modelli, è possibile modificare la richiesta e aggiungere un valore che consenta alla vista di sapere se l'utente è su un iPhone o meno. Quindi avvolgere render_to_response (o qualunque cosa tu stia usando per creare oggetti HttpResponse) per prendere la versione iphone del modello invece della versione html standard se stanno usando un iphone.

Altri suggerimenti

Rileva l'agente utente nel middleware, cambia i collegamenti url, guadagna!

Come? Gli oggetti richiesta Django hanno un attributo .urlconf, che può essere impostato dal middleware.

Dai documenti di django:

  

Django determina il root URLconf   modulo da usare. Di solito, questo è il   valore dell'impostazione ROOT_URLCONF, ma   se l'oggetto HttpRequest in arrivo ha   un attributo chiamato urlconf (impostato da   elaborazione delle richieste del middleware), relativo   il valore verrà usato al posto di   Impostazione ROOT_URLCONF.

  1. In yourproj / middlware.py, scrivi una classe che controlla la stringa 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. Non dimenticare di aggiungere questo a MIDDLEWARE_CLASSES in settings.py:

    MIDDLEWARE_CLASSES= [...
        'yourproj.middleware.MobileMiddleware',
    ...]
    
  3. Crea un urlconf mobile, yourproj / mobile_urls.py:

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

Sto sviluppando djangobile, un'estensione mobile di django: http://code.google.com / p / djangobile /

Dovresti dare un'occhiata al django-mobileadmin , che risolto esattamente questo problema.

Un altro modo sarebbe creare il proprio caricatore di modelli che carichi modelli specifici per l'agente utente. Questa è una tecnica piuttosto generica e può essere utilizzata per determinare dinamicamente quale modello deve essere caricato in base anche ad altri fattori, come la lingua richiesta (buon compagno per i macchinari Django i18n esistenti).

Django Book ha una sezione su questo argomento .

C'è un bell'articolo che spiega come rendere gli stessi dati con modelli diversi http://www.postneo.com/ 2006/07/26 / riconoscendo-the-mobile-web-con-django

Devi comunque reindirizzare automaticamente l'utente al sito mobile e questo può essere fatto usando diversi metodi (anche il tuo trucco check_mobile funzionerà)

Che ne dici di reindirizzare l'utente a i.xxx.com dopo aver analizzato la sua UA in un middleware? Dubito fortemente che agli utenti di dispositivi mobili piaccia l'aspetto dell'URL, tuttavia possono accedere al tuo sito utilizzando l'URL principale.

miglior scenario possibile: usa minidetector per aggiungere le informazioni extra alla richiesta, quindi usa il contesto di richiesta integrato di django per passarlo ai tuoi modelli in questo modo

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

quindi nel tuo modello sei in grado di introdurre cose come:

<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 soluzione semplice è quella di creare un wrapper attorno a django.shortcuts.render . Ho inserito il mio in una libreria utils nella radice della mia applicazione. Il wrapper funziona eseguendo automaticamente il rendering dei modelli in uno "mobile" o " desktop " cartella.

In 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')
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top