django

Desde principios de año estoy trabajando en yaco. Yaco es una pequeña empresa sevillana que se dedica a prestar servicios de consultoría y desarrollo de software libre y sobre todo desarrollo web con python tanto plone como django.
El funcionamiento de la empresa es parecido al de Emergya (empresa en la que estuve trabajando durante ocho meses) e incluso comparten una historia común, sin embargo tiene una serie de diferencias, por ejemplo emergya es prácticamente el doble de grande que yaco, y afronta casi todo tipo de proyectos, sin embargo yaco está más enfocada o especializada en el desarrollo de aplicaciones web.
Una empresa al fin y al cabo es un conjunto de empleados, y en esta empresa hay gente muy buena y muy inquieta, y por parte de la dirección se les permite pensar, opinar y desarrollarse. Un ejemplo de esto es el "día de proyectos personales" que es una iniciativa nueva de este año y que pretende brindar a los desarrolladores un día al mes para dedicar a desarrollar un proyecto propio. Es decir, que la empresa te dona parte de su tiempo para que lo dediques al proyecto software libre que a ti te parezca. Algo similar a lo que se hace en google, pero con menos recursos, por algo se empieza.
Pues bien, en principio voy a dedicar estos días de proyectos personales a seguir desarrollando sweetter y que no muera el proyecto. Mi idea principal es refactorizar todo el código, y corregir fallos que ahora que estoy desarrollando en django estoy descubriendo, y posteriormente surtir al proyecto con una serie de plugins útiles y empezar a buscarle rentabilidad o utilidad primero dentro de yaco, y después hacia nuestros clientes.
Y ya que estoy hablando de yaco, voy a contar las cosas que me gustan de trabajar aquí:
- Trabajo desarrollando en python y con software libre
- Hay gente con mucha experiencia e ideas interesantes, el equipo de trabajo es ideal y se puede trabajar de manera dinámica y ágil
- Los empleados están organizados, hay un delegado de personal que representa al conjunto de los empleados y todos conocen sus derechos
- Horario flexible y ajustable a tus necesidades
- La oficina está en el centro y puedo ir patinando
- La oficina es un lugar genial donde trabajar, está muy bien decorada, con las paredes pintadas con monigotes, hay una terraza, un sofá, en definitiva, se está como en casa
- Tenemos un futbolín y una wii en la oficina
- Hay comida y bebida gratuita en la oficina
- Cada vez que se consigue un proyecto nuevo hay desayuno gratis para todos, más conocido como campanazo, porque hay una campana que se toca cuando se consigue el proyecto.

Ahora que estoy trabajando con django estoy viendo lo potente que es, pero su sintaxis y forma de hacer las cosas no me acaba de convencer del todo comparandolo con web.py.
Una de las cosas que me gustan mucho de web.py es la forma de definir las vistas, que consiste en una clase donde defines el método GET y el método POST (no son obligatorios) y estos métodos son llamados según sea la petición http. Esto es muy util a la hora de hacer vistas de formularios, que si reciben la petición por GET muestran el formulario y si la reciben por POST hacen lo que sea con los datos, y en django suele haber un if request.method == 'POST' que guarrea la vista completamente.
Por eso hoy me he puesto y he hecho una pequeña prueba de concepto para poder permitir una definición similar en django, y así poder tener una mejor reestructuración del código de las vistas.
Lo he puesto en django snippets, pero también lo voy a poner aquí y lo comento:
from django.http import HttpResponse as response from django.http import HttpResponseNotAllowed class ViewClass: def __call__(self, request, *args, **kwargs): self.request = request methods = ['POST', 'GET'] self.methods = [method for method in dir(self)\ if callable(getattr(self, method)) and method in methods] if request.method in self.methods: view = getattr(self, request.method) return view(*args, **kwargs) else: return HttpResponseNotAllowed(self.methods) class IndexView(ViewClass): def GET(self): return response("all ok %s" % self.request.method) def POST(self): return response("all ok %s" % self.request.method) index = IndexView()
¿Qué es lo que he hecho? He definido mi vista IndexView como una clase, que hereda de "ViewClass" (ahí está la mágia), donde me he definido mis dos métodos, GET y POST, igual que si lo hubiera hecho con web.py, suponiendo que GET se llamará cuando la petición sea GET y POST cuando sea POST, y el request en lugar de recibirlo como parámetro es un atributo de la clase, así que accedo a él con self.request.
Luego defino la vista como index = IndexView(), una instancia de la clase IndexView.
ViewClass es la clase de la que heredamos y la que implementa el método __call__. En python, si un objeto tiene el método __call__ es callable, y se puede llamar igual que una funcion. Es más, en python, las funciones son objetos que tienen definido el método __call__. Por tanto, como django espera que la vista sea una función, no una clase, django va a llamar al método call y le va a pasar los argumentos de la vista.
En el método __call__ lo que se hace es mirar si el tipo de petición HTTP está implementado en la clase y es uno de los válidos (methods) y si existe en la clase un método con ese nombre, lo llama pasandole los argumentos y poniendo previamente self.request = request. En caso de que el método no esté implementado devuelve responsenotallowed.
Para terminar, quiero comentar que otra de las cosas que no me gusta de django es el sistema de templates, con tantas llaves y porcentages por ahí, me parece mucho más elegante templetor, pero también es verdad que los templates de django son muy potentes y se pueden hacer muchas cosas.


