Creando un blog con django – parte 2


Llego el momento de crear los modelos, pero antes analicemos los datos que necesitamos guardar. Nuestro blog tendrá post, comentarios y tags, los que a su vez se componen de:
  • Post: fecha, titulo, contenido y etiquetas.
  • Etiqueta: nombre.
  • Comentario: autor, fecha, contenido.
Ahora bien, una etiqueta puede estar relacionada con varios post, así como un post tener varias etiqueta, por lo que tienen una relación many to many. Los comentarios por otro lado solo pertenecen a un post por lo que necesitan una clave foránea que lo relacione con el respectivo post.

Teniendo claro el modelo de la base de datos, es hora de escribir el código necesario para crear las tablas, afortunadamente django nos facilita la tarea. Editamos el archivo models.py ubicado en la carpeta de la aplicación:
# 1
from django.db import models

# 2
class Tag(models.Model):
# 3
tag = models.CharField(max_length=100, unique=True, db_index=True)
# 4
def __unicode__(self):
return self.tag
Veamos que hicimos:
  1. Importamos el modulo models.
  2. Creamos una subclase de models.Model, 
  3. Cada columna de la bd es representada por un atributo, en este caso tag es de tipo caracter (CharField), existen otros tipos de campo según el valor almacenar. Los argumentos describen las propiedades del campo como la cantidad de caracteres que puede contener (max_length), que no se permiten valores repetidos (unique), ademas de hacer que se indexe (db_index) ya que es comun hacer búsquedas como: buscar todos los post con tag django.
  4. el método __unicode__ permite dar un nombre mas significativo a las instancias, este es utilizarlo en el sitio administrativo.
Sabiendo esto es fácil crear las demás tablas:
# post
class Post(models.Model):
# la relación many to many entre Post y Tag
tags = models.ManyToManyField(Tag, blank=True)
title = models.CharField(max_length=200)
body = models.TextField()
# fecha de publicación, se agrega fecha automáticamente
pub_date = models.DateField(auto_now_add=True)

def __unicode__(self):
return self.title

class Comment(models.Model):
# Cada comentario pertenece a un post
post = models.ForeignKey(Post)
# nombre es opcional (blank) y por defecto es Anonimus (default)
name = models.CharField(max_length=100, blank=True, default="Anonimus")
# el cuerpo del comentario
body = models.TextField(verbose_name="comment")
# fecha de publicación, se agrega fecha automáticamente
date = models.DateField(auto_now_add=True)

def __unicode__(self):
return "Por " + self.name + " en " + self.post.title
La clave foránea y relación many to many se crea en una simple linea de código. Ahora sincronizamos nuevamente y entramos al interprete de python para introducir información en la base de datos:
$ python manage.py syncdb
$ python manage.py shell
# importamos los modelos
from blog.models import Tag, Post

# aun no hay tags así que creamos una
django = Tag(tag="django")
django.save()

# creamos un post
new_post = Post(title="mi primer post", body="El primer post que realizo")
new_post.save()
# agregamos un tag y volvemos a guardar
new_post.tags.add(django)
new_post.save()
Como vemos, para introducir un registro en la base de datos creamos una instancia de la clase adecuada y seguidamente llamamos el método save, ¿pero como recuperamos un registro? existen tres métodos para consultar la base de datos:
  • get: retorna un solo registro, lanza una excepción si la consulta retorna cero o mas de un registro.
  • filter: retorna un array con los registros que coinciden la consulta o un array vacío.
  • exclude: similar a filter pero retorna los registros que no cumplen con la consulta.
Estos métodos se acceden a través del atributo objects que poseen las subclases de models.Model.
# recuperar todos los post
Post.objects.filter()

# recuperar los primeros 10
Post.objects.filter()[:10]
Para refinar la búsqueda usamos argumentos que corresponden con los campos de la tabla:
# post segun titulo
Post.objects.filter(title="mi primer post")
Los campos que son claves foraneas (Post.tags, Comment.post) son algo especial: podemos seguir la relación escribiendo el nombre de la columna seguido de dos guiones bajos (_), pudiendo acceder el modelo al que apunta dicha relación. veamos un ejemplo:
# post con tag django
Post.objects.filter(tags__tag="django")
Al usar tags__ ya no estamos mas en Post sino en Tag, ahora podemos consultar los campos de esta tabla (tag). otro ejemplo:
# comentarios de posts con tag django
Comment.objects.filter(post__tags__tag="django")
Seguimos la relación a Post (post__) y consultamos la columna tags__ lo que nos lleva a Tag donde finalmente consultamos el atributo tag o_O.

Con esto tenemos lista la base de datos, en la próxima parte veremos como crear plantillas para visualizar estos datos.

Muchas gracias por su atención, no olviden dejar sus sugerencias, inquietudes y amenazas en los comentarios, hasta la próxima.