Foros del Web » Programando para Internet » Python »

[SOLUCIONADO] Doble relación pero una sola opción

Estas en el tema de Doble relación pero una sola opción en el foro de Python en Foros del Web. Hola chicos, he venido aprendiendo mucho el tema de DRY en Django, pero aun sigo teniendo varios problemitas, supongamos el siguiente modelo: Tengo un Blog ...
  #1 (permalink)  
Antiguo 05/06/2013, 18:44
 
Fecha de Ingreso: julio-2011
Mensajes: 62
Antigüedad: 12 años, 9 meses
Puntos: 5
Doble relación pero una sola opción

Hola chicos, he venido aprendiendo mucho el tema de DRY en Django, pero aun sigo teniendo varios problemitas, supongamos el siguiente modelo:

Tengo un Blog y un Foro, ambas aplicaciones en teoría debería compartir otra aplicación que se requiere con una relación "ForeignKey".


Código Python:
Ver original
  1. #apps blog
  2. class Blog(models.Model):
  3.     title = models.CharField(max_length=100)
  4.     slug = models.SlugField()
  5.     description = models.TextField()
  6.  
  7. #apps foro
  8. class Foro(models.Model):
  9.     title = models.CharField(max_length=100)
  10.     slug = models.SlugField()
  11.     description = models.TextField()
  12.  
  13. #apps video
  14. from blog.models import Blog
  15. from foro.models import Foro
  16. class Video(models.Model):
  17.     blog = models.ForeingKey(Blog, null=True, blank=True)
  18.     foro = models.ForeingKey(Foro, null=True, blank=True)
  19.     title = models.CharField(max_length=100)
  20.     video_url = models.URLField()
  21.     created_at models.DateTimeField()
  22.     updated_at = models.DateTimeField()

La aplicación blog y foro no comparten los mismos atributos literalmente, de serlo se que podría heredar de otra clase abstract. Bueno básicamente tenemos la aplicación video que ambas aplicaciones harán uso. Que me recomiendan así esta bien o genero un modelo de video por cada aplicación:

Código Python:
Ver original
  1. class VideoAbstract(models.Model):
  2.     title = models.CharField(max_length=100)
  3.     video_url = models.URLField()
  4.     created_at models.DateTimeField()
  5.     updated_at = models.DateTimeField()
  6.  
  7.     class Meta:
  8.         abstract = True
  9.  
  10. class ForoVideo(VideoAbstract):
  11.     foro = models.ForeingKey(Foro)
  12.  
  13. class BlogVideo(VideoAbstract):
  14.     blog = models.ForeingKey(Blog)

Cual de estas opciones es mucho mejor, la idea del ejemplo primero es mantener todos los enlaces de video en una sola tabla y por el tema de DRY.

Gracias y un saludos
  #2 (permalink)  
Antiguo 05/06/2013, 19:44
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 1 mes
Puntos: 1360
Respuesta: Doble relación pero una sola opción

Pero depende muchísimo de la relación que tenga un foro o un blog con un video.

¿un foro|blog solo puede tener un video?
¿un foro|blog puede tener cero, uno o mas videos?
¿un video puede tener cero, uno o mas blogs?
¿un foro|blog puede tener cero, uno o mas videos y un video puede estar en varios foros o blogs?

La primera forma me parece inmantenible, ademas de que probablemente viole alguna regla de normalización de base de datos. Que pasa si el mismo video quiero que este en varios foros o blogs? Vas a tener también redundancia de datos.

La segunda forma parece ser mas elegante (a nivel python), pero la verdad es que no lo es, ya que si quieres el mismo vídeo en un foro y en un blog vas a tener redundancia de datos.

Mi recomendación seria esta (asumiendo relación muchos a muchos):
Código Python:
Ver original
  1. class Blog(models.Model):
  2.     title = models.CharField(max_length=100)
  3.     slug = models.SlugField()
  4.     description = models.TextField()
  5.  
  6. class Foro(models.Model):
  7.     title = models.CharField(max_length=100)
  8.     slug = models.SlugField()
  9.     description = models.TextField()
  10.  
  11. class Video(models.Model):
  12.     title = models.CharField(max_length=100)
  13.     video_url = models.URLField()
  14.     created_at models.DateTimeField()
  15.     updated_at = models.DateTimeField()
  16.  
  17. class VideoBlog(models.Model):
  18.     blog = models.ForeingKey(Blog)
  19.     video = models.ForeingKey(Video)
  20.  
  21.     class Meta:
  22.         unique_together = ('blog', "video")
  23.  
  24. class VideoForo(models.Model):
  25.     foro = models.ForeingKey(Foro)
  26.     video = models.ForeingKey(Video)
  27.  
  28.     class Meta:
  29.         unique_together = ('foro', "video")

De manera general no veo por que debes de guardar las relaciones que existen entre (foro o blog) y videos.

Otra cosa te recomiendo que busques y leas sobre normalización de base de datos.
  #3 (permalink)  
Antiguo 05/06/2013, 20:22
 
Fecha de Ingreso: julio-2011
Mensajes: 62
Antigüedad: 12 años, 9 meses
Puntos: 5
Respuesta: Doble relación pero una sola opción

Te describo mejor lo que no te mencione, Blog y Foro son dos aplicaciones, las llamo blog y foro, pero debería haberlas definido en el model BlogEntry y ForoEntry.

Un video en BlogEntry no se repite en ForoEntry. Cada Video es unico, estaba investigando sobre Generic relations pero aun no la entiendo muy bien, crees que sea la mejor opción para mi problema.

¿un foro|blog solo puede tener un video? = Puede tener varios vídeos por no repetidos..
¿un foro|blog puede tener cero, uno o mas videos? = No, debe contener por lo menos un Video.
¿un video puede tener cero, uno o mas blogs? = No, es un video solo puede estar en una sola entrada.
¿un foro|blog puede tener cero, uno o mas videos y un video puede estar en varios foros o blogs? No.

Gracias.

Última edición por forosanto; 05/06/2013 a las 20:32
  #4 (permalink)  
Antiguo 06/06/2013, 16:07
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 1 mes
Puntos: 1360
Respuesta: Doble relación pero una sola opción

Solamente es cuestión que jueges con el unique_together y/o los indice unique para que veas cual relación se te ajusta mejor.

Etiquetas: django, doble
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:56.