Triggers con Django en el modelo de datos
Me imagino que estareis disfrutando de unas merecidas vacaciones, no obstante, quiero ofreceros un nuevo artículo sobre Django. Noo no es un quick n dirty, jeje Se trata de un ejemplo de como implementar triggers en Django y su ORM. Para la realización de ésta tarea, tenemos varias opciones:
- Implementar directamente en nuestra view.py el trigger, lo cual es aceptable pero no muy elegante en términos de MVC.
- Implementar en el models.py nuestro trigger. Es el caso que vamos a revisar, ya que es el más cómodo de implementar y respeta de cierta manera el modelo de tres capas de Django.
- Crear independientemente del ORM de Django nuestro trigger, centrandonos en la base de datos que utilicemos. Esta solución no es muy cómoda, ya que si cambiamos por lo que sea de base de datos o de diseño de nuestro model, tendremos que implementar esos cambios en la base de datos elegida.
En términos de rendimiento, es obvio que el trigger nativo será más rápido, seguido de cerca por las dos primeras opciones, cuyo rendimiento debería ser equivalente en ambos casos. Pasando a nuestro ejemplo, vamos a partir de 2 tablas. Cuando actualicemos una, se actualizará la otra automáticamente, tras redefinir el método save() de nuestra tabla.
Así pues, el código sería el siguiente:
################################
# models.py
##########################################
from django.db import models
class Jugadores(models.model):
nombre=models.CharField(max_length=45) # 45 caracteres para definicion del nombre en Jugadores
class Ranking(models.model):
jugador=models.ForeignKey(Jugadores) # Clave que enlaza con Jugadores
puntos=models.IntegerField(default=0) # entero con total de puntos y 0 por defecto.
# Al ordenar Ranking por puntos, tendremos el ranking de jugadores
class Partidas(models.model):
jugador=models.ForeignKey(Jugadores) # Clave que enlaza con Jugadores
puntos=models.IntegerField(default=0) # puntos por partida
def save(self, *args, **kwargs): # redefinicion del metodo save() que contiene nuestro trigger
# Aqui ponemos el codigo del trigger -------
rank=Ranking.objects.get(jugador=self.jugador)
rank.puntos+=self.puntos
rank.save()
# fin de trigger ------
return super(Partidas, self).save( *args, **kwargs) # llamada al save() original con sus parámetros correspondientes
####################
# llamada en views.py
#####################
def anotaPuntos(request, idjugador, puntos):
jugador=Jugadores.objects.get(id=idjugador) # obtencion del jugador por id de jugador
partida=Partidas.objects.create(jugador=jugador, puntos=puntos) # creacion de partida
partida.save() # al salvar, se llama a nuestro trigger. Otra aproximación sería
return HttpResponse("ok") # crear directamente un método independiente con el trigger en
# Partidas
La explicación del código es trivial si sabeis algo de Django. Inicialmente, definimos 3 tablas. Una con los nombres de jugadores, otra que nos permitirá, en consultas, ordenando por puntos, obtener de forma rápida el ranking de jugadores (Ranking) y otra, Partidas. Esta última tabla la manejaremos con mayor asiduidad y contendrá el código de nuestro trigger, mediante la redefinición del método save(). Se parte de la suposición de que la tabla de Jugadores está creada y rellenada, así como la tabla Ranking. El código de anotaPuntos, se imagina que captura mediante un get los parámetros idjugador y puntos, seguidamente, obtiene el objeto del jugador correspondiente, para crear posteriormente una nueva partida terminada, que se actualizará mediante save(). Finalmente, se responde con un ok incondicionalmente.
Hasta aquí, nuestro artículo sobre triggers. Probad el código y experimentad con él. Como siempre, una duda, un comentario.
Saludos y
happy coding!!!
fuente: Stack Overflow
blog comments powered by