2009-11-18 14 views
17

Estoy tratando de crear una base de datos de django que registre todas mis compras de comics, y he encontrado algunos problemas. Estoy tratando de modelar la relación entre un tema de cómic y los artistas que trabajan en él.Relaciones de muchos a muchos con datos adicionales sobre la relación

Un problema cómico tiene uno o más artistas trabajando en el tema, y ​​un artista trabajará en más de un problema. Además, el artista tiene un rol relacionado con lo que hicieron en el creador de cómics (todo el trabajo sobre ese tema), escritor (escribió el guión), dibujante (dibujó el comic completo), lápices, tintas, colores o texto, y puede haber varios artistas en un rol dado.

Esto me da un modelo de base de datos como: Database model

entonces me traduce esto en el siguiente modelo de Django. Como requiero datos adicionales sobre la relación, creo que tengo que usar una clase separada para manejar la relación, y mantenga el adicional

class Artist(models.Model): 
    name = models.CharField(max_length = 100) 

    def __unicode__(self): 
     return self.name 

class ComicIssue(models.Model): 
    issue_number = models.IntegerField() 
    title = models.TextField() 
    artists = models.ManyToManyField(Artist, through='IssueArtist') 

    def __unicode__(self): 
     return u'issue = %s, %s' % (self.issue_number, self.title) 

class IssueArtist(models.Model): 
    roles = ((0, "--------"), 
       (1, "Creator"), 
       (2, "Writer"), 
       (3, "Drawer"), 
       (4, "Pencils"), 
       (5, "Inks"), 
       (6, "Colours"), 
       (7, "Text"), 
      ) 
    artist = models.ForeignKey(Artist) 
    issue = models.ForeignKey(ComicIssue) 
    role = models.IntegerField(choices = roles) 

Mis preguntas son:

1) ¿Esto parece una correcta forma de modelar esto?

2) Si no uso la función through='IssueArtist', puedo agregar relaciones usando la función artists.add(). Si uso esto, recibo un error 'ManyRelatedManager' object has no attribute 'add'. ¿Tengo que gestionar manualmente la relación creando instancias IssueArtist() y buscando explícitamente la tabla de relaciones? NB. Estoy usando Django 1.0, en este momento

Respuesta

22

Te recomiendo que veas la sección "CAMPOS ADICIONALES SOBRE MUCHAS A MUCHAS RELACIONES" en el Django documentation - cubre exactamente tu pregunta.

1: sí, crear un modelo de intermediario es el camino a seguir.

2: De la documentación: "A diferencia de muchos campos normales, no puede usar agregar, crear o asignar relaciones" - En cambio, para agregar Artista a un Issue, hágalo desde el intermediario modelo:

some_artist = Artist.objects.get(name='some name') 
some_issue = Issue.objects.get(tile='some tite') 
IssueArtist.objects.create(artist= some_artist, issue = some_issue, role=1) 
+0

Ese enlace es precisamente lo que estaba buscando y no encontrar. Creo que necesito ver mis habilidades de búsqueda. –

+0

Esta es una parte real de "mares agitados" de Django. El mensaje de error es engañoso y los métodos de agregar/crear realmente deberían funcionar como se esperaba. Gracias por publicar esta respuesta. – Rich

+2

solo indica que a.save() no es necesario si está utilizando el método create(). https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.create –

Cuestiones relacionadas