Pergunta

Eu fiz um site Django, mas eu bebi o Koolaid e eu quero fazer um IPhone versão. Depois de colocar muito pensamento em que eu vim acima com duas opções:

  1. Faça um outro local, como i.xxxx.com. Amarrá-lo para o mesmo banco de dados utilizando framework sites de Django.
  2. Encontre algum tempo de middleware que lê o user-agent, e muda os diretórios de modelos de forma dinâmica.

Eu realmente prefiro a opção # 2, no entanto; Eu tenho algumas reservas, principalmente porque a documentação Django desencoraja a alteração das configurações na mosca . Eu encontrei um trecho que iria fazer o que eu gostaria. A minha questão principal é tê-lo tão simples quanto possível, eu gostaria que fosse automagic e transparente para o usuário.

Tem mais alguém se deparar com o mesmo problema? Alguém gostaria de compartilhar sobre como eles combatida fazendo versões do iPhone de sites Django?

Atualizar

Eu fui com uma combinação de middleware e aprimorando a chamada modelo.

Para o middleware, eu usei minidetector . Eu gosto dele porque ele detecta um infinidade de user-agents móveis. Tudo o que tenho a fazer é verificar request.mobile em meus pontos de vista.

Para o tweak chamada template:

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

Eu uso isso para qualquer ponto de vista que eu sei que eu tenho ambas as versões.

TODO:

  • descobrir como o acesso request.mobile em uma versão estendida do render_to_response então eu não tenho que usar check_mobile ( 'template_name.html')
  • Usando o anterior automagicamente fallback para o modelo regular, se nenhuma versão móvel existe.
Foi útil?

Solução

Em vez de alterar os diretórios de modelos dinamicamente você pode modificar o pedido e adicionar um valor que permite a visualização saber se o usuário está em um iphone ou não. Em seguida, enrole render_to_response (ou o que você está usando para criar objetos HttpResponse) para pegar a versão para iPhone do modelo em vez da versão HTML padrão, se eles estão usando um iPhone.

Outras dicas

Detectar o agente do usuário em middleware, trocar as ligações URL, o lucro!

Como? Django solicitação objetos têm um atributo .urlconf, que pode ser definido pelo middleware.

De Django docs:

Django determina a raiz URLconf módulo para usar. Normalmente, esta é a valor da configuração ROOT_URLCONF, mas Se o objecto de entrada tem HttpRequest um atributo chamado urlconf (definido pelo processamento do pedido de middleware), a sua valor será utilizado no lugar do ROOT_URLCONF configuração.

  1. Em yourproj / middlware.py, escrever uma classe que verifica a string 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. Não se esqueça de adicionar este à MIDDLEWARE_CLASSES em settings.py:

    MIDDLEWARE_CLASSES= [...
        'yourproj.middleware.MobileMiddleware',
    ...]
    
  3. Criar um urlconf móvel, yourproj / mobile_urls.py:

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

Estou desenvolvendo djangobile, um django extensão móvel: http://code.google.com / p / djangobile /

Você deve dar uma olhada na django-MobileAdmin código fonte , que resolvido exatamente este problema.

Outra maneira seria criar o seu próprio carregador de modelo que carrega modelos específicos para o agente de usuário. Esta é uma técnica bastante genérico e pode ser usado para determinar dinamicamente o modelo tem de ser carregado dependendo de outros fatores também, como idioma solicitado (bom companheiro para existente máquinas i18n Django).

Django livro tem um href="http://www.djangobook.com/en/1.0/chapter10/#cn234" seção sobre este assunto .

Há um artigo bom que explica como processar os mesmos dados por diferentes modelos http://www.postneo.com/ 2006/07/26 / reconhecendo-a-mobile-web-com-django

Você ainda precisa automaticamente redirecionar o usuário para o site móvel, todavia, e isso pode ser feito usando vários métodos (seu truque check_mobile funcionará também)

Como sobre o redirecionamento do usuário para i.xxx.com após analisar seu UA em algum middleware? Eu duvido que os usuários móveis importo como url parecer, ainda que possam acessar seu site usando url principal.

melhor cenário possível: uso minidetector para adicionar a informação extra para o pedido, em seguida, usar o Django é construído no contexto de solicitação para passá-lo para seus modelos gosta assim

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

, em seguida, em seu modelo você é capaz de introduzir coisas 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>

Uma solução simples é criar um invólucro em torno django.shortcuts.render. Eu coloquei o meu em uma biblioteca utils na raiz do meu aplicativo. O invólucro funciona, tornando automaticamente modelos em uma pasta "móvel" ou "desktop".

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

Em view:

from utils.shortcuts import my_render

def home(request):    return my_render(request, 'home.html')
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top