Iniciando el grupo de Coding Dojo en Cochabamba Bolivia

2010 Enero 27
etiquetas: ,
por sergio hinojosa avila

Este año una de las metas propuestas es mejorar nuestro nivel de código, el anterior año estuvimos mas atentos a las practicas ágiles pero mas centrados en la parte del management, pero sin duda después de haberme iniciado como QA, luego hacer de developer y entrar al management, me doy cuenta que el management tienes mas allá de leer o tomar cursos es vivirlo y aplicarlo en casos reales y uno no puede enseñar buenas prácticas si nos la hace, en fin algo que siempre estuve buscando fue un grupo con el cual compartir y aprender experiencias y programar juntos, se que tuve un año muy flojo programando pero este año lo dedicaremos entero a mejorar nuestro código.

Aca les paso el resumen de nuestra primera reunión, cabe resaltar que el grupo fue iniciativa de rolando.

Bueno, nos reunimos entre antonio, rolando, jimmy y sergio (yo).

Hablamos de varias cosas y entre las que me acuerdo:

Se hablo sobre dos approaches para organizar el barcamp,
uno es “más ceremonial”, haciendo cartas para solicitar
ambientes, convocando estudiantes, poniendo fechas
con mucha anticipación etc.

Y la otra más espontánea, se propone una fecha, un problema
y nos juntamos para programar.

Se opto por la última, por que la primera require más organización,
etc. Que por ahora no es momento.

Bajo esa premisa se nos ocurrió realizar la primera sesión
aprovechando el Barcamp, este sábado 30 en la tarde
2-4pm

Hable con la organización y nos pueden habilitar un ambiente.
Nos encargamos de la portatil, y esta la opción de un data display.

Antonio va a realizar una charla pequeña en la mañana para explicar
de que trata el coding dojo e invitar a la gente.

Sobre el problema vamos a resolver este, que no es muy complicado
http://acm.uva.es/p/v101/10189.html

Sobre el lenguaje, se barajeo la opción de c, java pero se opto
por python, más que todo por los conocimientos frescos
sobre los unittest.

Para tomar en cuenta, al escoger el lenguaje hay que tomar en cuenta
que extrictamente se aplica TDD, ya sea con unittest u otro framework,
o puros asserts ;)

=== En resumen ===

Lugar:     Barcamp – Centro Manuela Gandarillas – Inmediaciones
América/Liberator
Fecha:    sábado 30/02
Hora:      14:00 – 16:00
Lenguage: python
Problema: http://acm.uva.es/p/v101/10189.html
Confirmados:
- Sergio
- Antonio
- Jimmy
- Rolando

=== /resumen ===

No hablamos sobre el estilo, pero supongo que aplicaremos randori
(rotación piloto/copiloto)

Luego tambien comentamos de ponernos más exquisitos y probar lenguajes nuevos:
clojure, erlang, scala, haskell, etc.

Y tambien de tratar hacer una sesión por semana, variando language/problema.

El lenguaje y problema pueden ser sometidos a votación, pero si entre dos o tres
se animan a convocar una sesión no hay problema, los demás apoyamos,
lo que menos queremos es burocracia :)

via: http://groups.google.com/group/dojo-cochabamba?hl=es

Instalación y configuración del Servidor y Cliente Git bajo ssh

2009 Marzo 23
etiquetas: , ,
por sergio hinojosa avila

Git es uno de los mejores versionadores distribuidos, si usas github pero quieres tener tu propio repositorio en tu casa o trabajo entonces esta es una simple solucion, que no te toma mas de unos minutos, esta misma configuracion la he probado en dreamhost y funciona de la misma manera, de echo deberia funcionar en cualquier host que tengas. Si quieres ademas poder publicarlo mediante http, entonces una muy buena opcion gitweb.  Gitosis es tambien otra opcion que tienes, que es muy parecido pero para algun proyecto simple creo que esto es suficiente.

1. Configuración del Servidor git

 

El único requisito es tener instalado git:

 

$ sudo apt-get install git-core

 

nota: El servidor esta configurado e instalado en django-server que tiene la IP 192.168.0.139, el usuario es django-server con password *****.

 

2. Configuración del Cliente git

 

Primero debemos generar el conjunto de llaves RSA:

 

$ ssh-keygen -t rsa

 

Luego debemos registrar nuestra llave publica en el servidor, dentro de las llaves autorizadas de ssh, como sigue:

 

$  cat .ssh/id_rsa.pub | ssh django-server@192.168.0.139 ‘cat >> .ssh/authorized_keys’

 

En caso de no tener git instalarlo:

 

$ sudo apt-get install git-core

 

Crear el archivo initrepo con el siguiente contenido:

 

$ vim initrepo

 

DOMAIN=django-server@192.168.0.139

ssh $DOMAIN ‘mkdir -p ~/git/’$1′.git && cd ~/git/’$1′.git && git –bare init’

mkdir $1

cd $1

git init

git remote add origin ssh://$DOMAIN/~/git/$1.git

touch .gitignore

git add .

git commit -m ‘Created new repo’

git push origin master

echo “

[branch \"master\"]

  remote = origin

  merge = refs/heads/master” >>.git/config

echo “Your new git repo ‘$1′ is ready and initialized at $DOMAIN/~/git/$1.git”

 

Asignarle los permisos:

 

$ sudo chmod a+x initrepo

 

Para iniciar un repositorio nuevo en la maquina remota solo es necesario ejecutar initrepo y pasarle como parámetro el nombre del repositorio:

 

$ ./initrepo test01

 

Inmediatamente veras una salida como esta:

 

Reinitialized existing Git repository in /home/django-server/git/test01.git/

mkdir: cannot create directory `test01′: File exists

Initialized empty Git repository in .git/

Created initial commit cccf28a: Created new repo

 0 files changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 .gitignore

Counting objects: 3, done.

Writing objects: 100% (3/3), 219 bytes, done.

Total 3 (delta 0), reused 0 (delta 0)

To ssh://django-server@192.168.0.139/~/git/test01.git

 * [new branch]      master -> master

Your new git repo ‘test01′ is ready and initialized at django-server@192.168.0.139/~/git/test01.git

 

Veras que en tu propia maquina tendrás la carpeta test01, ingresa y ya puedes empezar a hacer cambios y propagarlos en el servidor haciendo git push.

 

3. Obtener una copia de un repositorio remoto git y trabajar sobre el mismo

 

Para poder obtener una copia de un repositorio remoto primero deberá registrar su llave publica en el servidor remoto.

 

git clone ssh://django-server@192.168.0.139/~/git/test01.git

 

Luego puedes hacer cambios y replicarlos en el repositorio remoto con git push.

 

Referencias:

 

http://autopragmatic.com/2008/01/26/hosting-a-git-repository-on-dreamhost/

http://casperfabricius.com/site/2008/09/21/keeping-git-repositories-on-dreamhost-using-ssh/

http://madduck.net/blog/2007.07.11:publishing-git-repositories/

http://batterypowered.wordpress.com/2008/07/04/deploying-a-git-repository-server-in-ubuntu/

http://www.urbanpuddle.com/articles/2008/07/11/installing-git-on-a-server-ubuntu-or-debian

http://mechanicalrobotfish.com/posts/119-installing-git-server-using-gitosis

Instalando mod_wsgi, nginx y cmemcache en Ubuntu Intrepid para Django

2009 Marzo 21
por sergio hinojosa avila

Es un resumen breve para configurar nuestro servidor apache con mod_wsgi, memcache y nginx, el cual lo he recopilado de varios sitios, el cual espero pueda ser de ayuda y tambien pueda permitirnos a abrir debatos en lo que se refiere a las mejores practicas para configurar tus host para aplicaciones django.

Por que mod_wsgi y no mod_apache, puedes encontrar en este resumen mas detalles en los siguientes links:

Primero instalamos todos los paquetes requeridos:

$ sudo apt-get install subversion gcc curl
$ sudo apt-get install build-essential python-dev python-setuptools
$ sudo apt-get install python-egenix-mxdatetime memcached postfix

Para configurar memcache, necesitamos realizar dos pasos, el primero será inicializar memcache:

$ sudo memcached -u www-data -p 11211 -m 32 -d

(Inicializa memcached bajo el usuario www-data con 32 megabytes de ram)
Ahora necesitaremos construir el cmemcache, para ello obtenemos la siguiente librería:

$ sudo apt-get install libmemcache-dev

Ahora obtenemos el cmemcache y haremos un build del mismo:

$ wget http://gijsbert.org/downloads/cmemcache/cmemcache-0.95.tar.bz2
$ tar -xjvf cmemcache-0.95.tar.bz2
$ cd cmemcache-0.95
$ sudo python setup.py install

Instalación y configuración de Nginx

Primero debemos instalar nginx:

$ sudo apt-get install nginx

Luego inicializar nginx:

$ sudo /etc/init.d/nginx start

Podemos probarlo realizando curl 127.0.0.1 que nos devolverá una pagina html con titulo: Welcome to nginx!!

A continuación editamos la configuración básica de nginx, actualizando los siguientes datos:

$ sudo vim /etc/nginx/nginx.conf

worker_processes 4;  #4 indica que el servidor usa 4 procesadores
tcp_nopush on;       # activar esta línea
keepalive_timeout  2;
gzip  on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

Luego debemos añadir un nuevo archivo de configuración llamado proxy.conf que deberá contener lo siguiente:

$ sudo vim /etc/nginx/proxy.conf

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size           4k;
proxy_buffers               4 32k;
proxy_busy_buffers_size     64k;
proxy_temp_file_write_size  64k;

Puesto que nginx usa el Puerto 80 debemos cambiar la configuración de nuestro apache para que use el puerto 8080, para ello modificamos el archivo /etc/apache2/ports.conf y remplazamos el 80 por 8080.

Puesto que nginx no soporta la opción keepAlive debemos desactivar la misma en nuestro apache, para ello editamos el archivo /etc/apache2/apache2.conf y ponemos: KeepAlive off.

Ahora nos toca crear la estructura de directorios para nuestro dominio:

$ mkdir –p /home/<username>/webapps/<midominio>/{public,private,log,backup}

Para habilitar nginx en nuestro dominio debemos añadir nuestro dominio a los sitios habilitados y disponibles en nginx, para ello debemos añadir el siguiente archivo:

$ sudo vim /etc/nginx/sites-available/<midominio>

Cuyo contenido debería tener algo parecido a:

server {
listen 80;
server_name <midominio> www.<midominio>;
access_log /home/<username>/webapps/<midominio>/log/access.log;
error_log /home/<username>/webapps/<midominio>/log/error.log;

# main
location / {
proxy_pass              http://127.0.0.1:8080/;
proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real_IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size       4k;
proxy_buffers           4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location /media/ {
root    /home/<username>/webapps/<midominio>/public/;
}
}

Luego debemos crear un link del mismo archivo a sites-enabled:

$ sudo ln -s /etc/nginx/sites-available/<midominio> /etc/nginx/sites-enabled/<midominio>
$ sudo /etc/init.d/nginx restart

Para probar nginx, primero añadimos nuestro dominio al archivo de host usando nuestra ip.

$ sudo vim /etc/hosts

Dicho archivo debería verse algo asi:

127.0.0.1      localhost
<mi ip>       www.<midominio>

Luego en un browser ingresar a tu dominio y debera aparecer la pagina de error de nginx.

Instalar y Configurar mod_wsgi, con apache, nginx

Obtenemos mod_wsgi para nuestro servidor apache:

sudo apt-get install libapache2-mod-wsgi apache2-mpm-worker apache2-threaded-dev

En primera instancia debemos deshabilitar los sitios por defecto de apache:

$ sudo a2dissite 000-default

Asignamos los permisos correctamente:

$ sudo usermod -a -G www-data <username>

- Aseguramos que el directorio /home/<username>/webapps sea de <username> y que además este en el grupo www-data:

$ sudo chgrp -R www-data /home/<username>/

Nos aseguramos que todos los archivos nuevos de nuestro directorio webapps, heredaran los permisos:

$ sudo chmod -R 2750 /home/<username>/webapps

Otorgar permisos de escritura al usuario apache en el directorio privado de nuestro dominio:

$ sudo chmod -R 2770 /home/<username>/webapps/<midominio>/private

Obtener tu proyecto django y colocarlo dentro del directorio /home/<username>/webapps/<midominio>/

A continuación creamos el archivo wsgi:

vim /home/<username>/webapps/<midominio>/miproyecto.wsgi

El cual tendrá el siguiente contenido:

import os, sys
sys.stdout = sys.stderr

if ‘/home/<username>/webapps/<midominio>’ not in sys.path:
sys.path.append(‘/home/<username>/webapps/<midominio>’)
if ‘/home/<username>/webapps/<midominio>/<miproyecto>’ not in sys.path:
sys.path.append(‘/home/<username>/webapps/<midominio>/<miproyecto>’)
os.environ['DJANGO_SETTINGS_MODULE'] = ‘<miproyecto>.settings’

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

Por ultimo lo que nos toca es configurar el virtual host en el apache.
$ sudo vim /etc/apache2/sites-available/<midominio>

<VirtualHost *:8080>
ServerName www.<midominio>
ServerAlias <midominio>

<Directory /home/<username>/webapps/<midominio>/<miproyecto>/>
Order deny,allow
Allow from all
</Directory>

LogLevel warn
ErrorLog   /home/<username>/webapps/<midominio>/log/apache_error.log
CustomLog  /home/<username>/webapps/<midominio>/log/apache_access.log combined

WSGIDaemonProcess <midominio> user=www-data group=www-data threads=25
WSGIProcessGroup <midominio>
WSGIScriptAlias /  /home/<username>/webapps/<midominio>/<miproyecto>/<miproyecto>.wsgi
</VirtualHost>

Creamos un link del archivo para colocarlo entre los sitios habilitados de apache:

Ln –s /etc/apache2/sites-available/<midominio> /etc/apache2/sites-enable/<midominio>

Por ultimo le decimos a apache que agregue nuestro dominio:

$ sudo a2ensite <midominio>
$ sudo /etc/init.d/apache2 reload

Reiniciamos nuestro apache y listo!! Tenemos nuestro dominio en www.<midominio>

Referencias:
http://articles.slicehost.com/2008/5/16/ubuntu-hardy-nginx-virtual-hosts
http://www.meppum.com/2009/jan/17/installing-django-ubuntu-intrepid/
http://lethain.com/entry/2007/jul/17/dreamier-dream-server-nginx/
http://lethain.com/entry/2009/feb/13/the-django-and-ubuntu-intrepid-almanac/

Django – Managers que sobreescriben el get_query_set

2009 Enero 30
etiquetas: , ,
por sergio hinojosa avila

Los managers son una interfaz por encima de los modelos de django, que nos permiten realizar consultas sql relacionadas al modelo al cual están relacionados.

Django nos provee para todos los modelos un manager por defecto (objects), el cual nos provee una buena cantidad de consultas en forma de funciones (all, filter, exclude, etc)

Los managers los usamos en dos formas, una para sobreescribir el queryset que viene dado por defecto, y el otro para extender funcionalidad o extender nuestra gama de consultas que podemos realizar al modelo.

Sobreescribiendo el queryset

Cuando? si necesitas que ciertas instancias (tuplas de datos en la BD) no sean mostradas, entonces reducimos los resultados mostrados por el queryset que viene por defecto.

A continuacion escribimos un manager propio, en el cual sobreescribimos el queryset par devolver uno filtrado, que solo me muestre objetos que esten activos.

class CustomManager(models.Manager):
def get_query_set(self):
return super(CustomManager, self).get_query_set().filter(activo=True)

Class Empleado(models.Model):
nombre_completo = models.CharField(max_lenght=100)
activo = models.BooleanField(default=True)

A continuacion existen dos alternativas, la primera es sobreescribir el manager que viene por defecto y es accesido usando el nombre de objects, tambien puedes designarle un otro nombre, pero ya no podras llamar al atributo objects ya que al definir uno propio como se llame, objects ya no es mas disponible a menos que lo definamos explicitamente.

objects = CustomManager()

En el caso definido arriba, objects solo maneja los objetos empleado activos (activo=True), por lo cual:

Empleado.objects.all()

listara todos los empleados activos.

Por otro lado si se desea mantener objects, entonces debemos:

objects = models.Manager()
activos = CustomManager()

De esta manera tenemos:

Empleado.objects.all() que nos lista todos los empleados
Empleado.activos.all() que nos lista todos los empleados activos

El orden como se los define es importante, ya que el default manager, que es invocado por el admin, sera el que primero sea definido.

Django Forms – Sobreescribiendo los valores iniciales de un formulario dinámicamente.

2009 Enero 26
etiquetas: ,
por sergio hinojosa avila

Lo que se quiere:

Mantener el ítem seleccionado dentro de un dropdown list, después de que el usuario realice un submit, se requiere que el campo seleccionado por el usuario se mantenga seleccionado.

Lo que se nos provee por defecto:

Una vez que el cliente presiona submit, los valores de nuestro formulario son restablecidos a los por defecto (campos en blanco y sin selección).

Solución 1:

Guardar el ítem seleccionado en la sesión del usuario (para mayor seguridad), luego; cada vez que se cree el formulario, verificar si existe en la sesión el ítem seleccionado, si existe: entonces pasarlo dentro de los valores iniciales que tomara nuestro formulario.

Ejemplo:

Usaremos un formulario que permita seleccionar un usuario e ingresar/guardar sus horas de trabajo semanales, y que tambien pueda navegar a través de las semanas pasadas y posteriores, para dicha navegación requeriremos que el empleado seleccionado se mantenga seleccionado.

Dentro de nuestro ModelForm sobreescribimos nuestro init:

def __init__( self, request, *args, **kwargs ):
report = None
if ‘do’ in request.POST:
start_date = parsedate(request.POST['hidden_start_date'])
else:
if request.session.__contains__(‘employee’):

# En esta sección verifico si esta guardado nuestro empleado seleccionado en la sesión, si es así, obtengo el empleado seleccionado.

employee=request.session.get(‘employee’)
report = TimeReport.objects.extra(where=['employee_id=%s', 'company_id=%s', 'start_week_date=%s'], params=[employee, request.user.client.pk, start_date])

# A continuación sobreescribiremos los valores iniciales de nuestro formulario y le agregaremos como valor inicial que este seleccionado el empleado que sacamos de la sesión.

initial = {‘employee’: employee }
initial.update(kwargs.get(‘initial’, dict()))
kwargs['initial'] = initial
super( TimeReportForm, self ).__init__( *args, **kwargs )

Solución 2:

En la vista, verificar si el usuario ha seleccionado un cliente, si es así, crear el formulario y pasarle los valores iniciales (el empleado seleccionado):

if ‘employee’ in request.POST:
form = TimeReportForm(request)
form.initial = {‘employee’: request.POST['employee'] }

En esta segunda solución tan simple, existiría varias ventajas y solo una desventaja,

Ventajas:

Menos código, ya no es necesario guardar y recuperar una variable de sesión y tampoco sera necesario realizar operaciones extras.

Desventaja:

La selección del empleado no se recordara durante la vida de la sesión del usuario como ocurre en la primera solución.

DRY – Dont Repeat Yourself, Django esta pensado en facilitarte muchas necesidades muy comunes.

DRY – Filtrando elementos en un campo de tipo ModelChoiceField

2009 Enero 13
etiquetas: ,
por sergio hinojosa avila

Muchas veces descuidamos algunos detalles al leer la documentacion o simplemente no la entendemos, Dont Repeat Your Self es algo que debemos aplicar en todo momento, mas aun cuando usamos frameworks como Django, donde siempre existe una forma mas sencilla de hacer las cosas.

En el ejemplo siguiente, sobreescribo la manera de construir un formulario, especificamente: De lo aplicantes quiero que solo se muestren los que han sido seleccionados como empleados, en el campo employee:

class PayRollForm(forms.ModelForm):
def __init__( self, *args, **kwargs ):
super( PayRollForm, self ).__init__( *args, **kwargs )
self.fields['employee'] = forms.ModelChoiceField(queryset = Applicant.employees.all(), label=_(‘Employee’))
class Meta:
model = PayRoll

En la ultima linea sobreescribo el queryset, pasandole un nuevo queryset pero que solo contiene la lista de empleados.

Es asi fue como resolvi la primera vez que empezaba a jugar con django. Despues de leer detenidamente la documentacion y tratando de no perder detalles, encontre que la solucion a mi problema, era tan simple como:

Model PayRoll(models.Model):
employee = models.ForeignKey(Applicant, verbose_name =_(‘Employee’), related_name=’employee_payroll’, limit_choices_to = {‘is_employee’: True})

El atributo limit_choices_to nos permite filtrar los datos a ser mostrados en un campo que recibe llaves extranjeras.

Basto con una linea para resolver mi problema, lo bueno fue que aprendi a sobreescribir mis formularios y a prestar mayor atencion a a los detalles en la documentacion de Django.

Anuncio del lanzamiento de la Segunda Version del Libro Oficial de Django (para la version de Django 1.0)

2009 Enero 9
etiquetas:
por sergio hinojosa avila

Adrian Holovaty nos anuncia en su blog del lanzamiento de la Segunda Version del Libro Oficial de Django, el cual ahora no contiene incompatibilidades con la actual version de Django 1.0.

Durante este periodo fue realmente una tragedia para muchos que se iniciaban en Django al no tener a la mano Libros que esten totalmente actualizados de acuerdo al a Version 1.0.

Enlaces de interes:

Adrian en Twitter, nos mantendra informados de los avances.
Los borradores del libro que son gratis y estan en linea.

El tour de Corey “Tour de Programacion en parejas”

2008 Diciembre 23
por sergio hinojosa avila

Realmente fantastico, Corey Haines lleva adelante su tour denominado “Pair-Programming Tour 2008″, lleno de nuevas experiencias y donde hace prevalecer que la experiencia de trabajar en parejas te lleva a aprender y compartir mucho mas que del modo simple y solitario.

Quien es Core Haynes?

Corney Haines, paso el ultimo año casi exclusivamente desarrallonado con Ruby on Rails, antes de ello paso 5 años desarrollando con C#. Y durante los ultimos 4 años ha estado dirigiendo e implementando tecnicas de desarrollo agil, como la programacion en parejas, BDD y TDD.

Actualmente se encuentra sin empleo, pero con algunos ahorros en el bolsillo y con la ayuda de sponsors, ahora lleva adelante este evento, que tambien es parte de lo que pretendia hacer como uno de sus siguientes pasos en su carrera profesional. Obviamente cuando acabe el tour quedara sin dinero practicamente y necesitara conseguir un empleo.

Mas datos del evento:

Core Haines ha creado un blog exclusivo para el evento, Corey Haines’ Pair Programming Tour.

A continuacion una breve lista de las entrevistas con los personajes que tuvo la oportunidad de trabajar en pareja:

Fue todo un tour el que lleve adelante en el blog de Corey y fueron muchas las horas que me tomo para ver cada una de las entrevistas, pero sin duda estas experiencias son las que nos enriquecen y las que dificilmente encontraremos en libros, blogs, etc.

Hoy es el ultimo dia de Pownce

2008 Diciembre 15
etiquetas: ,
por sergio hinojosa avila

Goodbye Pownce, Hello Six Apart, es asi como titula el post que nos recuerda que hoy es el ultimo dia de esta gran aplicacion echa en django, y tal cual lo refleja su creadora leah, ahora junto a mike, seran parte del equipo de ingenieros de Six Apart. Esperemos que pronto tengan nuevas noticias y puedan traernos sorpresas para la gran comunidad de django.

Si quieres seguirlos en esta nueva proeza, podemos encontrar sus blogs en vox:
leahculver.vox.com, Mike en mjmalone.vox.com, y Ariel en arielwaldman.vox.com.

Anuncio oficial de Six Apart, dando la bienvenida al equipo de pownce:
http://www.sixapart.com/blog/2008/12/welcome-pownce-team.html

Creando modelos y registrandolos en la interfaz de administracion en Django

2008 Diciembre 14
etiquetas: , ,
por sergio hinojosa avila

Django viene con muchas aplicaciones reutilizables directamente añadidas al core o a la version de distribucion, entre una de ellas, de echo la mas utilizada, es la de administracion “django.contrib.admin“.

El admin de django te permite tener una interfaz administrativa para tus modelos, el unico requisito es que las registres, a continuacion recrearemos una pequeña aplicacion llamada todo manager.

Para habilitar el admin, debemos añadirlo a nuestro settings.py

INSTALLED_APPS = (
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.sites’,
‘django.contrib.admin’,
‘todomanager’, # nuestra aplicacion que vamos a crear mas adelante
)

Sobre el proyecto  ahora crearemos una nueva aplicacion que se llame todo:

#./admin.py start-app todo

Django nos crea los archivos models.py y views.py por defecto en el nuevo directorio de nuestra aplicacion que lleva el mismo nombre que el que le dimos.

Abrimos el models.py y a continuacion definimos los modelos de nuestra aplicacion:

(archivo: models.py)

from django.db import models
from django.utils.translation import ugettext_lazy as _

# ugettext_lazy es parte de la aplicacion de internacionalizacion de django y viene junto al core de django, el objetivo es que podamos mostrar tanto el contenido como las funcionalidades en varios idiomas, para añadir esta caracteristica usaremos textos traducibles de la forma _(‘texto a ser traducido’).

from django.contrib.auth.models import User 
#django nos provee otra aplicacion que maneja la autenticacion, en el todo el modelo User nos servira para representar al dueño.

from datetime import datetime

class Todo(models.Model):
HIGH = 3
MEDIUM = 2
LOW = 1
CHOICES_PRIORITY =(
(HIGH, _(‘High’)),
(MEDIUM, _(‘Medium’)),
(LOW, _(‘Low’))
)
COMPLETED = 1
TBD =2
CHOICES_STATUS=(
(COMPLETED, _(‘Completed’)),
(TBD, _(‘To be Done’))
)

A continuacion escribimos los campos que tendra nuestro modelo, django nos provee unos tipos basicos de fields, entre ellos tenemos el foreignkey que nos permitira relacionar nuestra entidad debil con una fuerte. En nuestro caso un User sera dueño de uno o mas todos.

owner = models.ForeignKey(User, related_name=’owner_group’, verbose_name=_(‘owner’))

#  el atributo related se usa para indentificar desde el Usr al conjunto de “todos” que le pertenecen, mientras que el verbose name es la cadena que se usara para representar a ese campo.

name = models.CharField(_(‘name’), max_length=32)

# el tipo Charfield tiene como atributo obligatorio definir un maximo de letras de contenido, que sera un entero mayor a 1

created_date=models.DateTimeField(default=datetime.now)

# el atributo default lo usamos para definir valores por defecto, el valor por defecto sera la fecha de hoy, now la pasamos como callbak (se ejecutara la funcion now cada vez que se la requiera)

priority = models.IntegerField(_(‘priority’), choices=CHOICES_PRIORITY)
status = models.IntegerField(_(’status’), choices=CHOICES_STATUS)

# El atributo choices nos permite pasarle una lista de valores validos para dicho campo

description = models.TextField(_(‘description’))
due_date = models.DateField(_(‘due_date’),blank=True,null=True,)
completed_date = models.DateField(_(‘completed_date’),blank=True,null=True)

class Meta:
ordering = (‘created_date’,'priority’)
verbose_name = _(‘Todo’)
verbose_name_plural = _(‘Todo List’)
unique_together = (“owner”, “name”)
get_latest_by = ‘created_date’
order_with_respect_to=’owner’

# Estas son algunas de las opciones que tenemos para definir los metadatos de nuestro modelo, estos se definen definiendo la clase interna Meta. (En otro post veremos con mas detalle las difrentes opciones, aunque muchas de elas son faciles de predecir)

def __unicode__(self):
return self.name

# el unicode django automaticamente nos proveera el metodo __str__() que llamara a nuestro metodo _unicode__ y entonces convertira el resultado del mismo a una codificaciion de cadena de objetos UTF-8 correctamente. Para versiones mayores de django 1.0 es aconsejable usar unicode y no asi str.

Para que nuestro modelo pueda ser tomado en cuenta por el admin de django debemos registrarlo, para ello dentro de nuestra aplicacion creamos el archivo admin.py y lo minimo requerido para registrarlo seria tener lo siguiente:

(archivo: admin.py)

from django.contrib import admin

from models import Todo

admin.site.register(Todo)  # aca registramos nuestro modelo con el admin de django

Ahora nos toca generar la base de datos:

./admin.py syncdb

Simepre la primera vez que sincronizamos nos pedira registremos las credenciales de nuestro usuario administrador (dile yes :P ).

Para habilitar completamente las interfaz administrativa debemos editar el urls.py de nuestro proyecto y tener algo como sigue:

from django.conf.urls.defaults import *
from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns(”,
(r’^admin/(.*)’, admin.site.root),
)

Ahora podemos hacer correr nuestro proyecto con:

#./manage.py runserver 0.0.0.0:8000

Ahora nos vamos al browser y colocamos:

http://127.0.0.1:8000/admin

Usando las credenciales que registramos al realizar el sync de bd ingresamos al sitio de administracion de djano.

Sin duda esta caracteristica de django es la que atrae a muchos, ya que en la mayoria de las aplicaciones que realizamos siempre necesitamos tener esta interfaz administrativa, aunque existen muchas cosas que se estan mejorando aun, no cabe duda que el admin de django nos ahorrara mucho trabajo.