Mudança Django Templates Com base User-Agent
-
03-07-2019 - |
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:
- Faça um outro local, como i.xxxx.com. Amarrá-lo para o mesmo banco de dados utilizando framework sites de Django.
- 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.
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.
-
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"
-
Não se esqueça de adicionar este à MIDDLEWARE_CLASSES em settings.py:
MIDDLEWARE_CLASSES= [... 'yourproj.middleware.MobileMiddleware', ...]
-
Criar um urlconf móvel, yourproj / mobile_urls.py:
urlpatterns=patterns('',('r'/?$', 'mobile.index'), ...)
Este artigo pode ser útil: Criar um aplicativo móvel e desktop-friendly em Django em 15 minutos
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')