A Django site.
Marzo 3, 2010
» os.path en el settings.py de Django para mayor comodidad

En el archivo de configuración settings.py de un proyecto Django, por lo general tenemos que setear variables como MEDIA_ROOT o STATIC_DOC_ROOT. Su contenido en una instalación Windows suele ser algo como: 'C:\Windows\camino\hasta\mi\projecto'. Y en Linux: '/home/usuario/camino/a/mi/proyecto'. El problema surge cuando el proyecto es desarrollado en varias máquinas a la vez, y con distintos sistemas operativos. Más aún, si hacemos lo anterior, seguramente versionaremos el proyecto y con él, al archivo de configuración. No sería raro que tras una actualización, el archivo se actualice con los valores que puso algún compañero de trabajo.

Mi solución es definir primero una variable para el proyecto:

PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))

Luego podemos usarla para definir el path absoluto a la carpeta con archivos de media:

MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')

nuestros templates:

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(PROJECT_PATH, 'templates')
)

o cualquier otra variable de configuración que requiere una ruta de directorios.

Con esta solución podemos cambiar el proyecto de carpeta, disco o computadora y seguirá funcionando.

Agosto 15, 2009
» Django Middleware

Mientras estudié el tema para hacer un experimento, traduje el 80% de la documentación oficial. La dejo aquí más algunos condimentos personales.

Middleware

Es un sub framework que permite modificaciones al sistema de procesamiento de request/response de Django. Es un sistema de plugins liviano y de bajo nivel que permite alterar globalmente las entradas y salidas de Django.

Cada componente middleware es responsable de hacer alguna función específica.

Activar componentes middleware

Para hacerlo, añadirlo a la lista MIDDLEWARE_CLASSES en la configuración de Django (settings.py). En esta lista, cada componente se representa por un string: el camino completo al nombre de la clase. Por ejemplo:

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)

En el tratamiento de requests y la generación de responses, existen dos faces:

1) Fase Request (se llama a los métodos process_request() y process_view())
2) Fase Response (se llama a los métodos process_response() y process_exception())

En la primera, las clases son aplicadas desde la primera a la última, según el orden de la lista mencionada. En la segunda fase, se aplican en orden inverso; podemos pensarlo como una cebolla:

middleware

Una instalación de Django puede funcionar sin ningún middleware, pero esto no es recomendado.

Para escribir middleware propios

Cada componente es una clase Python, que no tiene que extender a ninguna clase en particular y debe definir uno o más de los siguientes métodos.

process_request(self, request)

request es un objeto HttpRequest. El método es llamada por cada request, antes de que Django decida que vista ejecutar.

Debe retornar None o un objeto HttpResponse. Si retorna None, Django seguirá procesando el request, ejecutando los otros middlewares y luego la vista apropiada. Si retorna un objeto HttpResponse, Django no hará nada más, solo retornar ese objeto.

process_view(self, request, view_func, view_args, view_kwargs)

request es un objeto HttpRequest. view_func es la función Python que Django está por usar. (Es el objeto function, no el nombre de la función en un string). view_args es un alista de argumentos posicionales que serán pasados a la vista. Y view_kwargs es un diccionario de argumentos de palagra clave que serán pasados a la vista. Ni view_args ni view_kwargs incluye al primer argumento de la vista (request).

process_view() es llamado antes de que Django ejecute la vista. Debe retornar None o un objeto HttpResponse. Si retorna None, Django seguirá procesando el request, ejecutando otros process_view() y luego la vista apropiada. Si retorna un objeto HttpResponse, Django no hará nada más, solo retornar ese objeto.

process_response(self, request, response)

request es un objeto HttpRequest. response es un objeto HttpResponse retornado por una vista de Django.

process_response() debe retornar un objeto HttpResponse. Puede altener el objeto response dado o puede crear uno nuevo.

A diferencia de proces_request() y process_view(), este siempre es ejecutado.

process_exception(self, request, exception)

request es un objeto HttpRequest. exception es un objeto Exception lanzado por la vista.

Django llama a process_exception() cuando la vista lanza una excepción. process_exception() debe retornar None o un objeto HttpResponse. Si retorna un objeto HttpResponse, la respuesta es devuelta al navegador. De lo contrario, el sistema por defecto para manejo de excepciones entra en acción.

__init__

Por lo general estas clases no tienen estado; simplemente contienen a los anteriores métodos. Se puede usar el método __init__ pero se debe tener en cuenta que Django inicializa estas clases sin argumentos y que el método __init__ es llamado solo una vez, cuando el servidor web arranca.

Experimento

Con lo anterior en mente, me quedaron algunas dudas al respecto:

  • si modifico los argumentos de view_func en process_view y retorno None, ¿estos son pasados modificados a la vista?
  • si lo anterior es falso, puedo lograr el mismo efecto haciendo:
    def process_view(self,request, view_func, view_args, view_kwargs):
        # modificar request, view_args y view_kwargs
        return view_func(request, view_args, view_kwargs)

    ?

  • ¿puedo definir process_response de tal forma que examine response?

Mayo 4, 2009
» URLs elegantes con Django

Este texto es parte del informe de nuestro proyecto final de carrera, lo publico en forma separada aquí por que tiene valor propio y puede convencer a más de un programador PHP de probar Django. Las URLs elegantes son la forma natural de las URL en Django.

Manejo de URLs

Tener URLs elegantes y limpias es un requisito común para aplicaciones web modernas. Django provee un mecanismo de manejo de URLs basado en expresiones regulares que asocia una expresión regular a una vista.

Para diseñar las URLs de una aplicación Django, se construye una especie de tabla que mapea patrones de URL a funciones Python a ejecutar (vistas). Con esto se logra que las URLs estén desacopladas del resto de la aplicación.

El siguiente es un ejemplo de una entrada de esa tabla:

(r'^index/$', index)

Suponiendo que la aplicación web está corriendo en el servidor con nombre localhost, cuando alguien acceda a http://localhost/index/ se ejecutará la vista ‘index’.

El siguiente es un ejemplo un poco más complejo:

(r'^cliente/datos/(\d+)/$', cliente_datos)

En el patrón de la URL se utilizan paréntesis para capturar una parte de la misma y poder accederla luego como parámetros en la vista. La expresión encerrada entre paréntesis se denomina grupo y son propias de las expresiones regulares en Python. Así, siempre que se acceda a, por ejemplo, http://localhost/cliente/datos/1/ o http://localhost/cliente/datos/100/ se ejecutará la vista cliente_datos y recibirá como parámetro el número correspondiente.

Algo similar sucede en el siguiente ejemplo:

(r'^inmueble/fotos/(\d+)/eliminar/(\d+)/$', eliminar_foto)

Con la diferencia de que ahora la vista recibe dos parámetros, en este caso particular el primero corresponde a un identificador de inmueble y el segundo a un identificador de foto.

Las expresiones regulares en Python soportan también lo que se denomina grupos nombrados. Esto permite obtener un grupo por su nombre. Si escribimos una especificación de URL como la siguiente:

(r'^inmueble/fotos/(?P<inmueble>\d+)/eliminar/(?P<foto>\d+)/$', eliminar_foto)

la vista será llamada utilizando parámetros nombrados. Esto tiene la ventaja de que si cambia el orden de los parámetros en la URL, la vista seguirá funcionando sin que se necesite redefinirla.

Marzo 27, 2009
» FPDF en Django

Si intentás usar FPDF en Django hay algunas cosas que necesitás saber:

  • (ya sabés qué) FPDF está originalmente escrita en PHP y permite generar documentos PDF sin usar PDFLib (C).
  • (ya sabés qué) hay más de un port de esta librería a Python. Todos son incompletos.
  • Usá este http://www.nsis.com.ar/svn/pyfpdf/ (parcheado en Argentina para utilizar unicode).
  • FPDF trabaja con la codificación ISO-8859-1.
  • Mi código fuente Django usa la cotificación UTF-8 y en los documentos resultantes aparecían caracteres raros en lugar de vocales con tilde o eñes.
  • Lo soluciné haciendo una modificacicón en el método Output:

self.buffer = buffer.encode('iso-8859-1')

Noviembre 24, 2008
» El mejor hosting para Django

Según DjangoFriendly, el mejor hosting para Django es Webfaction. Yo lo vengo probando por un mes y estoy muy satisfecho.

Noviembre 4, 2008
» humitos

Aunque fui hace algúnas semanas ya, no tuve la oportunidad de escribir nada al respecto y tampoco quería dejar de asentar este viaje, ya que fui muy importante para mí.

Lo primero que hice, como siempre, fue avisar en el trabajo que iba a faltar un día: el viernes. Debido a que eran algo así como 10 o 12 horas de viaje y las jornadas empezaban el viernes a las 9hs. Por esto, saqué el pasaje para el Jueves a las 21hs y estaba llegando a eso de las 5:30 am con el horario de San Luis.

El viaje en sí, estuvo bueno. El colectivo salió a horario y llegó a horario, un punto aceptable. Además durante el trayecto, comí como un chancho (nos dieron comida de verdad, osea carne con puré y una entrada antes con un buen vino tinto, muy rico), después jugamos al Bingo Andesmar, algo raro para un micro pero divertido. Lástima que no gané nada :(

Con el cansansio que tenía y el vino que me había clavado, ya estaba parpadeando demasiado, asique decidí dormir. En la mitad del trayecto me desperté porque estábamos pasando por una ruta de tierra y no se podía respirar dentro del colectivo, era insoportable, me puse la remera en la nariz pero era muy fuerte la tierra… Pensé lo peor :P

Ni bien llegué, me estaban esperando los chicos de San Luix con algunos otros disertantes. Desayunamos algo en una panadería cerca de la termina, la que luego se convertiría en el punto principal de la ciudad :D , mientras esperábamos a más disertantes que venían de distintos lugares. Después nos fuimos a la casa de Marcelo, quien me alojaba, para dejar los bolsos y demás. Cerca de las 9am partimos para la facultad.

Como en todo evento, primero lo primero: abrieron con un acto de inauguración en dónde hablaba Marcelo Alaniz, el decano de la facultad, la gente del laboratorio de informática y alguien más. Terminado esto comenzó la charla de María Elena Casañas: ¿Qué es el software libre?, la cual como nunca había visto, me quedé a escuchar y me gustó mucho, me sorprendió la buena onda que le pone y lo linda que está armada la charla. Lo bueno es que es bien bien introductoria, y toca muchos aspectos que un recién iniciado o alguien que ni siquiera sabe lo que es el software libre necesita saber. Me gustó mucho la charla y no me aburrí para nada aunque ya conozca todos los conceptos que se tocaron.

Entre esta charla y la de Marcelo me puse a armar el stand, aunque estaba sólo como loco malo, me dí maña y colgué la bandera que había llevado de “Python en Santa Fe”, pusé una mesita con la OLPC y unos cuantos mini-tutoriales que habían sobrado de la jornada que se hizo acá. Fue un poco loco, porque ni bien saqué la OLPC se empezó a hacer bastante gente, no toda junta pero sí cada uno que pasaba le pegaba una mirada y lo cazaba con “la promo“. Mucha gente se copó, sobre todo los que estaban dedicados a la docencia en las distintas áreas. Creo que fue bastante productivo. Además los mini-tutoriales desaparecieron enseguida…

La próxima charla que vi fue la de Marcelo Alaniz: Yarara, la navaja suiza del web, que hablaba sobre un framework que él hizo como tesis de su facultad. Tocó muchos temas similares a lo que sería mi charla al día siguiente, ya que Yarará tiene cosas muy parecidas a Django. Me gustó de este que es muy configurable según lo que contó, ya que cada uno puede usar lo que trae o bien definir cosas nuevas o usar otras ya existentes pero que no son parte de Yarará, por ejemplo el ORM.

Esta fue la última charla de la mañana, y luego el almuerzo. Con algunos chicos de San Luix y otros disertantes nos fuimos a comer al comedor universitario de la facultad a un par de cuadras de esta. Ni bien llegamos nos encontramos con los chicos de Buenos Aires que no podían creer los precios que tenían en este comedor. Resumiendo, hicimos una cola de 10′ – 15′ y nos sirvieron dos pedazos de carne al horno con salsa, ensalada, pan y una naranja por $3,75, si, si… Tres con setentaicinco centavos, increíble. Además estaba exquisito!

Cuando volví, hacía un ratito que había empezado la charla de Facundo de la Cruz y Marcelo Alaniz, Mi amiga la consola, la cual fue un show de Facundo frente al público. La charla en sí trata de cómo reemplazar los programas gráficos por programas en modo texto, mostrando que se puede hacer todo lo mismo y mucho más con una terminal de caracteres. Muy interesante la charla, aprendí algunas cosas nuevas y reforcé algunas que no me acordaba :)

Ni bien terminó esta, un poquito tarde, me fui volando para Tecnologias web que la daba Juan Pablo Stange, quien mostró qué cosas son necesarias para encarar un sitio web, desde la explicación del protocolo http y como es la interacción con apache y el browser hasta un framework de javascript que hizo él para hacer cosas locas como con jQuery. Me gustó mucho la charla, el loco le puso mucha onda, fue gracioso y aprendí bastante. Cerró la charla apagando la máquina mediante un sms que le llegaba a su celular y con una aplicación web le daba al shutdown, grossini!

Después de esta charla, yo ya estaba muerto… Pero muerto, muerto. Tenía muchas ganas de descanzar, había viajado toda la noche sin dormir muy bien, y se empezaba a notar. Hablé con Marcelo y con un amigo de él, no recuerdo el nombre, pero sí recuerdo que era muy groso el loco. Entre otras cosas se había hecho un modelador 3D en C, dejate de joder!!!

Fuimos a la oficina de él, nos mostró un par de cosas, entre ellas el modelador y algunas cosas de Ruby, le comenté sobre Rubinius y se copó bastante, hablamos un rato al pedo mientras disfrutábamos del aire acondicionado y hablábamos al pedo. Nos mostró la antena que se compró: Nanostation. ¡Cosa que se zarpa desde donde lo mires!

De ahí nos fuimos a la casa de Marcelo a descanzar, pero ni bien llegamos uno sacó la notebook, después sacaron la antena y a los 5 minutos estábamos colgados de la ventana tratando de alcanzar más redes con un par de vasos de fernet en la mano :) . No alcancé a terminar el primer vaso, que como bien macho me ofrecí a que me lo preparen como se toma en San Luis, ya estaba dormido arriba del puf! :P

En algún momento de la noche me pasé a la cama, no recuerdo bien, estaba molido. Pero al final cuando me levanto eran cerca de las 7:30 hs, hora en la que había puesto el despertador, asique ya me quedé despierto mirando un poco el techo y juntando ganas para levantarme, sacando nervios porque a las 9hs era mi charla y pensando en probarla antes para ver si funcionaba todo ok.

Al levantarme, recuerdo que Marcelo se había ido y que estaba sólo en la casa. Le mando un mensaje para ver como hacíamos y me dice que estaba lloviendo como loco, yo ni lo había notado, pero cuando miro por la ventana no parecía tanto: raro. Pasan varios llamados y mensajes en el medio, no conseguíamos remises o taxis por ningún lado y se acercaba la hora de mi charla. Marcelo me comentaba que no sólo es que estaba lloviendo sino que estaba inundada la ciudad y era un quilombo movilizarse, que quizás se suspendían las jornadas… Uhhh!

La cuestión es que al final Marcelo agarró un paraguas que tenía donde estaba, juntó mucho coraje y se mandó a saltar por arriba de todos los charcos para llegar hasta la casa de él, en donde estaba yo. Cuando llega empezamos a contactar a toda la gente con auto para que nos pase a buscar y nos lleve a las jornadas. Al rato pasa Damián en auto y nos vamos derecho para las jornadas, aunque ya era tarde para mi charla :(

Pregunté cómo podíamos arreglar y qué podía hacer con mi charla… Si había venido gente a la mañana y qué pensaban hacer con el resto de las charlas. Coordiné para poder darla a las 11hs, aunque no estaba muy contento porque era un horario el cuál nadie sabía que iba a estar mi charla, pero bue… Otra no me quedaba, lo único que les dije es que para la próxima manejen el tema de la lluvia (podían hacer llover otro día) :D

Cerca de las 11 me puse en el pasillo de la Universidad a reclutar gente para mi charla, diciendo las palábras máginas: “En 10 minutos arranca una charla buenísima sobre Django en este aula” :) , aunque no conseguí mucha audiencia vinieron algunos engañados…

En general, me gustó como salió la charla. Lo único que no me gustó como salió, fue que la máquina tenía ubuntu con compiz y se colgueteaba mal cuando quería hacer Alt+Tab de la presentación al vim. Un garrón! Después de la segunda vez, no desactivamos y pude seguir adelante. Pero por otro lado, me gustó que pude decir todo lo que quería, no me quedé con nada para decir, aunque si bien tuve que ocupar un poco de la charla que seguía debido a los inconvenientes del compiz y demás. Hubo algunas preguntas interesantes, o por lo menos que parecía que habían entendido lo que dije… Salvo uno que me preguntó que era el patrón MVC, por lo que supongo que ese no entendió nada. Lástima que no puedo recordar si esa persona había llegado tarde o estaba cuando lo expliqué y no se entendió. Espero que haya sido lo primero, porque sino quiere decir que soy malísimo :D

Inmediátamente después de mi charla vino la de Damian Noceda, Mercurial: Sistema de control de versiones, que me gustó mucho. El tipo me convenció de que Mercurial es lo mejor que hay y no le podía discutir, me cambió totalmente el concepto que tenía en general sobre los sistemas distribuidos. A pesar de que la charla fue zarpada, al menos para mí ya que me sirvió muchísimo, sospecho que tenía algo, no sé… Algo que no puedo especificar muy bien, quizás sea que esa PC corria Windows XP y estábamos en una jornada de Software Libre (algún palo se tenía que comer por eso :) )

Luego de esta charla, fuimos a por comida. Compramos unos sandwiches buenísimos en la panadería del desayuno con algunas empanadas y volvimos rápido porque empezaba la charla Blender: Softaware 3D, libre y creativo que daba Oliver Perfumo. Asique comimos en el aula mientras esperábamos que empiece.

Esta charla en particular: se zarpó. El loco tiene muchos años de experiencia en el diseño en 3 dimensiones y algunos años también con el uso de blender. Mostró un video-propaganda de lo que ha hecho en su empresa re zarpado. De momentos no le creía, era muy bueno. Explicó las cosas básicas de blender y la locura que tienen los desarrolladores en la cabeza, la interfaz loca que tiene y algunas cosas más. Mostró muchas cosas, pero muchas, blender es muy zarpado: esqueletos, formas, tipos de datos, scripts en Python, dibujó una cara on-the-fly, peinó un mono… No sé… ¡Se zarpó mal este flaco! La charla terminó mostrando los dos cortos que hizo la gente de fundación blender: Elephants Dreams y Big Buck Bunny.

Seguida de esta vino Llaves PGP / GPG de dererk, quién durante 1,5 horas intentó explicar que era esto. Pero se colgó bastante con la introducción, más allá de que estuvo buena la charla, me hubiese gustado que no se cuelgue taaaanto con el traceroute para explicar porqué era necesario y/o útil utilizar esta tecnología. Lamentablemente lo terminaron echando del aula porque se había pasado, y mucho. Igualmente me gustó la charla, fue entretenida y diferente, con decir que arrancó diciendo: “No tengo slides preparados ni nada, voy a mostrar cosas en la pantalla y hablar nomás… Asi que veamos como sale”

Hasta acá llegué con las charlas que ví, luego de esta última me quedé hablando con Oliver sobre blender y el software libre. Me cayó muy bien el loco, hablamos una cantidad sobre filosofía y demás, nos colgamos bastante. Después cayó Marcos, el chico de Musix, y también nos colgamos hablando bastante, muy copado ambos.

Luego vino el acto de cierre, se dijeron algunas palabras, agradecimientos y demás: robé un agradecimiento a Python Argentina :) , habló la gente del laboratorio y terminaron las jornadas. Nos fuimos derechito a la ya “clásica” panadería a tomar cervezas y a comer algo. Pasado un rato de cervezas, chistes, nerdiadas y demás decidimos partir a algún lugar donde comer algo más pulenta y levantamos campamento. Terminamos en un pub-boliche bastante lindo comiendo unas pizzas espectaculares y tirándole onda a la moza entre 15 más o menos. Comimos unas galletas con mayonesa casera que era excelente, parecía queso, no podía ser tan rica. Obviamente ninguno adivinó que era mayonesa, nadie lo podía creer…

Pasado un buen rato, como yo no conocía nada de San Luis todavía, le propuse a un grupo salir a dar una vuelta por ahí y tomar algo en algunos otros bares, como para conocer un poco más. Nos fuimos un grupo de 5 o 6 caminando por ahí y terminamos en pool (sin poder jugar :( ) contando diferentes aventuras/historias en viajes que cada uno había realizado por el software libre.

Al otro día, me levanté a eso de las 13 hs. Me quería matar, habíamos organizado para ir al medio de la montaña: un lugar llamado Potrero para comer un asadaso. Enseguida me puse en contacto con los chicos y me dijeron que ya estaban allá, me indicaron como llegar y demás. Justo en este momento llegan unos chicos de Buenos Aires que estaban en auto y salimos volando para allá.

Cuando llegamos nos perdimos un poco dando vueltas por todos lados, pero al fin los encontramos. Comimos muy poco asado, ya que la mayoría se había llenado con porquerías como ser papitas y coca. En algún momento fuimos algunos a buscar unas cervezas que las habíamos dejado en el río para que no se calienten. Yo me quedé arriba de un murito que había ahí y algunos otros bajaron, cuando me doy vuelta para volver al asado escucho como que pisé una rama y cuando miro para abajo dije: “No…”, hice mierda los lentes de Ezequiel que los había dejado en el murito justo detrás de donde estaba yo. No sabía que decirle, pero bueno… “son cosas que pasan” :(

Terminado el asado, nos fuimos a explorar la montaña entre todos, estuvo buenísimo. Caminamos entre un montón de rocas y cuando llegamos a un lugar bastante peligroso cortamos, aunque algunos decidieron estalar la montaña completa y llegar a la cima. Y no sólo eso, sino que también Juan Pablo subió su notebook y comprobó que en el pico de la montaña hay wifi ¡Que groso!

Cuando bajaron todos, pegamos la vuelta hacia dónde estaba el auto y hacia donde pasaba el colectivo para volver a San Luis. Nos encontramos en la terminal y cada cual a su colectivo. Salíamos todos más o menos a la misma hora.

Saludé a todos y me subí al micro. A los 5′ – 10′ veo que está subiendo a mi mismo colecto “Chaco” o mejor dicho “Robocop”, uno de los disertantes que había venido de Chacho a dar la charla de “Robocoders”. Por suerte hablamos bastante en el viaje, aunque yo estaba liquidado y tenía muchas ganas de dormir porque ni bien llegaba me iba al trabajo. Nos cagamos de la risa, es un capo el loco.

A las 7:30 hs llegué a la terminal y me fui volando al trabajo, con una cara de muerto-vivo pero al trabajo al igual… ¡Fue un día durísimo!

¿Cuándo se hacen las próximas jornadas de software libre en San Luis? ¡Ahí
estaremos!


Noviembre 2, 2008
» SQL Debug en Django

¿Cómo saber en Django qué sentencias SQL se están ejecutando detrás de su ORM? Según la FAQ, podemos hacerlo de esta forma:

Make sure your Django DEBUG setting is set to True. Then, just do this:

>>> from django.db import connection
>>> connection.queries
[{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls',
'time': '0.002'}]

connection.queries is only available if DEBUG is True. It’s a list of dictionaries in order of query execution. Each dictionary has the following:

“sql“ — The raw SQL statement
“time“ — How long the statement took to execute, in seconds.

connection.queries includes all SQL statements — INSERTs, UPDATES, SELECTs, etc. Each time your app hits the database, the query will be recorded.

Cada vez que se realiza una nueva petición, esa variable es sobre escrita con las consultas que se ejecutaron en la vista asociada. La forma de verlas es accediendo a connection.queries en cada vista de nuestro interés. Para facilitar esta tarea y no tener código intrusivo, escribí un decorador:


from django.db import connection
def sql_debug(f):
'''
Decorador útil para inspeccionar las sentencias SQL que se ejecutan en
cada request.
'''
def inner(*args, **kwargs):
r = f(*args, **kwargs)
for d in connection.queries:
print "time: %s\n sql:%s\n\n" % (d['time'], d['sql'])
return r
return inner

Octubre 31, 2008
» humitos

¡Sí, increíble pero verídico! Don Richard Stallman va a estar en Argentina el próximo Lunes 3 de Noviembre charlando de lo que realmente sabe (cualquier cosa puede decir, es un groso) en el Salón Auditorio del Anexo de la Honorable Cámara de Diputados de la Nación. ¡Muchas gracias a Vía Libre por romperse el culo para organizar algo de semejantes características y por todo el apoyo que me dieron!

Como no podía ser de otra manera, hice lo imposible para poder asistir. Se me complicó bastante, ya que el pasado fin de semana estuve de viaje en San Luis dando una charla de Django (Introducción a Django) en las jornadas de esta ciudad (sobre la cual comentaré luego) y ya había faltado el Viernes al trabajo. Además el colectivo que me tomé el domingo se demoró mucho en las paradas que tenía programadas y no alcancé a llegar a horario al trabajo, de hecho llegué unos 45′ tarde.

Además de tener que pedir… Otro día más en el trabajo, tenía que juntar la plata (más bien, gastar lo poco que tenía ahorrado) para poder viajar. A todo esto hay que sumarle que mañana al medio día me estoy yendo a Córdoba al 2do PyDay que se va a realizar en la tecnológica de esta ciudad. Por lo tanto, voy a andar haciendo un ping pong por todo el país.

Corto acá, tengo que hacer el bolso, terminar la charla, contestar emails y algunas cosas más… ¡Estoy al horno!


Octubre 30, 2008
» Diagrama de capas de Django

¿Cuál sería un diagrama de capas correcto para representar una instalación de Django? Ensayé el siguiente gráfico; es para una instalación en particular, pero se puede cambiar GNU/Linux por Sistema Operativo, PostgreSQL por Base de Datos y Apache por Servidor Web para hacerlo más genérico:

La idea detrás de un diagrama de capas es expresar que los componentes de una capa le brindan servicios a los de la capa superior mediante alguna interfaz.
¿Mejores ideas? ¿Conviene otro tipo de diagrama?

Octubre 24, 2008
» Generar diagramas de clases a partir de modelos de Django

La siguiente es la mejor forma que encontré de tomar todos los archivos models.py de las aplicaciones que componen un proyecto Django y generar un diagrama de clases completo, listo para exportar cómo imagen. Utilizo un comando incluido en django-command-extensions.

Obtener e instalar django-extensions

Para Django 1.0 hay que bajar la última versión del svn:

svn checkout http://django-command-extensions.googlecode.com/svn/trunk/ django-command-extensions

E instalarlo ejecutando el script de instalación:

cd django-command-extensions
sudo python setup.py install

Podemos probar si se instaló correctamente abriendo una consola Python y ejecutando:

>>> import django_extensions

Para que este disponible en nuestro proyecto debemos agregar la aplicación a settings.py:

INSTALLED_APPS = (
...
'django_extensions'
)

Cuando ejecutemos:

python manage.py help

veremos una lista de los nuevos comandos disponibles.

Generar archivo .dot

Uno de ellos es graph_models el cual nos permitirá generar un archivo en formato .dot:

python manage.py graph_models -a > mi_proyecto.dot

Generar archivo .png

O una imagen png:

python manage.py graph_models -a -g -o mi_proyecto.png

Para que el anterior comando funcione, necesitamos tener instalado pygraphviz. En mi Ubuntu no tenía el paquete python-pygraphviz por lo que tuve que bajarlo desde su página web. Para instalarlo requiere tener instalados los paquetes graphviz y graphviz-dev.

Ejemplo

El siguiente comando genera el diagrama de clases para auth, la popular aplicación que viene con Django y sirve como ejemplo de cómo generar el diagrama para solo una aplicación del proyecto:

python manage.py graph_models auth -g -o mi_proyecto_auth.png

Nota

Les recomiendo bajar la versión de pygraphviz empaquetada de Cheeseshop en lugar de la del svn, ya que con esta el comando de django-extensions lanza una excepción. Correguí el programa, abrí un ticket y envié un parche. Para cuando leas esto probablemente ya se haya incorporado a trunk.

Octubre 20, 2008
» Banner

El próximo Viernes y Sábado en la ciudad de San Luis se hacen las primeras Jornadas de Software Libre, a las cual asistiré como disertante para dar la charla “Introducción a Django” en la cual voy a intentar mostrar qué es Django, cómo se empieza un proyecto y algunas cosas más para los que todavía no lo conocen. El contenido de la charla es muy sencillo pero me parece que puede llegar a estar muy buena si me sale bien y no me pongo nervioso.

Por el momento me siento seguro del contenido pero como siempre tengo un poco de nervios al momento de hablar. Lástima que no tuve la posibilidad de probarla, si se quiere, frente a público antes de ir para allá a darla de verdad.

Del lado de los organizadores, tengo que decir que se portaron de diez en todo. La comunicación que hemos tenido y la buena onda que me han brindado habla muy bien de ellos. De momento tengo entendido que me va a alojar uno de ellos, que si no me equivoco, es el creador del framework Yarará, Marcelo Alaniz. Asique vamos a tener muchas cosas para hablar supongo…

Salgo el Jueves 23 a las 21hs de acá de Santa Fe (20hs de San Lius :P ) y llego a las 5:30hs de San Luis… Lo que se me complicó para entender esto no tiene precio. Esto de que algunas provincias tengan una hora y otras otra es una locura… Tendría que ir cambiando la hora del celular a medida que voy pasando entre las distintas provincias hasta que llegue a San Luis :P . ¡Arriba del cole nunca voy a saber qué hora es realmente!

Update: la estadía del viaje está comentada acá


Agosto 5, 2008
» custom tags en django

Luego de combatir durante un rato largo y encontrar poca documentacion los custom tags en django, paso a escribir un resumen de como crearlos:

Antes que nada los custom tags son una suerte de funciones que aplicamos a las variables que queremos imprimir en los templates
Ej en PHP:

strtoupper($variable);

Ej en Django:

{{ variable|upper }}

Se entendio la idea? Continuemos

Digamos que tenemos la aplicacion “contenido” la cual vendria a ser una suerte de tabla de un blog.
Y el tree se veria algo asi:

/djangoapp
 __init__.py
 settings.py
 urls.py
 manage.py
 templates/
   base.html
 contenido/
   __init__.py
   models.py
   views.py

En el archivo templates/base.html tenemos todo lo que vamos a mostrar, que podria verse de la siguiente manera:

{{ titulo }}
{{ texto }}

Que al intentar visualizarlo, veremos algo asi:

este es el titulo
este es el texto

Cuando en realidad, lo que queremos es que el resultado final sea el siguiente:

<h1>este es el titulo</h1>
<p>este es el texto</p>

Nota: si bien podriamos escribir los condenados tags HTML, vamos a hacer que se auto-escriban como un custom tag.

Bien, para lograr esto primero debemos crear un directorio llamado ‘templatetags’ dentro de nuestra aplicacion ‘contenido’ y dentro del nuevo directorio, creamos dos archivos mas:
* __init__.py : Este archivo lo debemos crear para que el directorio funcione como un modulo y podamos utilizarlo.
* custom_tags.py : Aca vamos a escribir nuestros tags.

Luego de haber hecho esto, el tree de nuestra djangoapp deberia ser algo similar a esto:

/djangoapp
 __init__.py
 settings.py
 urls.py
 manage.py
 templates/
   base.html
 contenido/
   __init__.py
   models.py
   views.py
   templatetags/
     __init__.py
     custom_tags.py

Escribimos los custom tags en el archivo custom_tags.py:

from django import template
register = template.Library()

@register.filter
def str_to_h1(s):
    return u'<h1>%s</h1>' % s

@register.filter
def str_to_p(s):
    return u'<p>%s</p>' % s

Ahora que ya tenemos todo listo, solamente resta cargar nuestros nuevos tags al principio del template (lease ‘base.html’ o cualquier archivo que utilicemos para mostrar contenido):

{% load custom_tags %}

{{ titulo|str_to_h1|safe }}
{{ texto|str_to_p|safe }}

Nota: El tag ’safe’ que agregue es para que Django no escape al HTML.

Ya habiendo realizado todo eso, deberiamos poder visualizar nuestro ejemplito como queriamos al principio.

Por cierto, si por alguna razon no esta funcionando, asegurense de que en la tupla INSTALLED_APPS en el archivo settings.py este incluida la aplicacion a la cual le agregamos los custom tags.
Ej:
INSTALLED_APPS = (’djangoapp.contenido’,)