Django cambiar de lenguaje desde el view

Para cambiar el LANG en el servidor, asumiendo que tenemos todo el sistema de traducción correctamente configurado, llamamos via POST a la ficha setlang y le pasamos el campo language con la lengua seleccionada:

En settings definimos los lenguajes con los que trabajamos:

LANGUAGES = (
    ('es', ugettext(u'Español')),
    ('de', ugettext(u'German')),
    ('en', ugettext(u'English')),
);


En urls, incluimos las url de i18n:

(r'^i18n/', include('django.conf.urls.i18n')),


Y ya en el template podemos llamar a la ficha /i18n/setlang para setear el lenguaje:

<li class="gbt">
<form name="setLangSpanish" action="/i18n/setlang/" method="POST">{% csrf_token %}
<input name="next" type="hidden" value="/" />
<input type="hidden" name="language" value="es" />
<a href="#" class="language_off" onclick="document.setLangSpanish.submit();return false;">
<span class="language_off sprachwahl">Español</span></a>
</form>
</li>
<li class="gbt">
<form name="setLangEnglish" action="/i18n/setlang/" method="POST">{% csrf_token %}
<input name="next" type="hidden" value="/" />
<input type="hidden" name="language" value="en" />
<a href="#" class="language_off" onclick="document.setLangEnglish.submit();return false;">
<span class="language_off sprachwahl">English</span></a>
</form>
</li>
<li class="gbt">
<form name="setLangDeusch" action="/i18n/setlang/" method="POST">{% csrf_token %}
<input name="next" type="hidden" value="/" />
<input type="hidden" name="language" value="de" />
<a href="#" class="language_off" onclick="document.setLangDeusch.submit();return false;">
<span class="language_off sprachwahl">Deusch</span></a>
</form>
</li>


Fuente: oscarcp http://blog.oscarcp.com/?p=163

Mysql borrado rápido filas duplicadas

En este sitio he encontrado una forma muy rápida de eliminar duplicados. Tan rápida que puede hacerse con una sola línea, se trata de crear ununique index con la palabra clave IGNORE. Tal que esto:

ALTER IGNORE TABLE dupTest ADD UNIQUE INDEX(a,b);


Guay eh?

Django filtro de query usando un string

Es común que queramos pasar directamente un string al filtro de una consulta, por ejemplo, desde una url. Dado que el parámetro de filter es un diccionario, lo podemos hacer mediante el operador de desempaquetado de diccionarios **.

Recordemos que para desempaquetar una lista usamos el operador * y para desempaquetar un diccionario el **:

Ejemplo de *


>>> pepe=(1,10,)
>>> range(pepe)
Traceback (most recent call last):
File "", line 1, in
TypeError: range() integer end argument expected, got tuple.
>>> range(*pepe)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Ejemplo de **



>>> pepe={ "venus" : "blanco", "tierra": "azul", "marte": "rojo" }
>>> '{tierra}'.format(pepe)
Traceback (most recent call last):
File "", line 1, in
KeyError: 'tierra'
>>> '{tierra}'.format(**pepe)
'azul'
>>>


En ambos ejemplos observamos que al usar * o ** pasamos con el tipo correcto. Pero ¿Cómo aprovecharlo para pasar directamente un filtro a la consulta?. Yo lo hago de la siguiente forma:


# un string
filtro="nacionalidad__exact@ESP"
# lo parseamos en clave-valor
f=filtro.split("@")
# pasamos como diccionario
p=Persona.objects.filter(**{f[0]:f[1]})
# el efecto es el mismo que hacer
p=Persona.objects.filter(nacionalidad__exact='ESP')

Y ahora veamos cómo implementarlo.

En la página web:

$('a.pais').click(function() {
   var pais=$(this).attr("pais");
   $('#{{entidad}}').load("?filtro="+escape('nacionalidad__exact@'+pais)+"&type=ajax");
});


Notemos que en la url pasamos,
  1. Un interrogante: Hará un get sobre la página actual.
  2. Un nombre de parámetro (filtro). Si queremos añadir más parámetros los separamos con &
  3. El valor del parametro poniendo un igual después del nombre, por ejemplo,  filtro=nacionalidad__exact@ESP 
En la parte del servidor lo que hacemos es procesar directamente el filtro pasando de string a diccionario así:


def get_filtro( self, request):
  """ aplica el filtro y devuelve el modelo filtrado """
   filtro=request.GET.get('filtro', False)
   if filtro:
  try:
     f=filtro.split('@')
     return Persona.objects.filter(**{f[0]:f[1]})
   except Exception, e:
    logger.error('desempaquetando filtro '+str(e))

   return Persona.objects.all()


La ventaja de este método es que es muy sencillo crear toda clase de filtros directamente en la página web teniendo un solo código que los gestiona en el servidor. 

Una última puntualización: Si no todos los usuarios pueden ver todo el modelo i.e. ver todas las personas Persona.objects.all() hay que ir con cuidado ya que es muy sencillo manipular a mano la url para que nos devuelva cualquier registro. Por ejemplo:

?filtro=moroso__exact@1

Nos devolvería todos los morosos ;-)



Reproducir vídeos en la Nexus 10 por USB

De forma nativa no podemos conectar un disco externo o pen drive a la Nexus para reproducir vídeo. Para poderlo hacer precisamos dos cosas:

  1. Que la Nexus nos haga de "host" USB para que pueda leer desde dispositivos USB.
  2. Eventualmente, poder reproducir el formato AVI.

Conexión del dispositivo USB a la Nexus 10

Necesitamos un cable OTG (USB On-the-go) para poder conectar el dispositivo (hembra) en el micro-usb de la tablet. Son muy baratos y se encuentran en cualquier tienda de componentes o electrónica.






También necesitamos que el sistema operativo nos reconozca el dispositivo. Como android no lo hace, tenemos que instalar software. Una aplicación que funciona sin problemas (no es necesario entrar como root) es Nexus Media Importer. Basta con conectar el dispositivo y ya tendremos acceso al contenido del disco.



Reproducción de AVI

Hay muchos buenos programas que reproducen AVI y mantienen los códecs actualizados. Yo uso el MX Player Pro, al que podemos activar la decodificación por hardware (en la pestaña de Configuración-Decodificación)