2010-03-15 15 views
6

Hay Tengo una pregunta sobre las relaciones.django ManyToMany a través de la ayuda

Quiero que los usuarios tengan amistades. Entonces un Usuario puede ser un amigo con otro Usuario. Asumo que necesitaré usar ManyToManyField, a través de una tabla de Amistad. Pero no puedo hacer que funcione. ¿Algunas ideas?

Aquí están mis modelos.

class User(models.Model): 
    username = models.CharField(max_length=999) 
    password = models.CharField(max_length=999) 
    created_on = models.DateField(auto_now = False, auto_now_add = True) 
    updated_on = models.DateField(auto_now = True, auto_now_add = False) 
    friends = models.ManyToManyField('self') 
    pendingFriends = models.ManyToManyField('self', through='PendingFriendship', symmetrical=False, related_name='friend_requested') 

class PendingFriendship(models.Model): 
    user = models.ForeignKey('User', related_name='user') 
    requested_friend = models.ForeignKey('User', related_name='requested_friend') 
    created_on = models.DateField(auto_now = False, auto_now_add = True) 
    updated_on = models.DateField(auto_now = True, auto_now_add = False) 

Gracias

Respuesta

6

muchos-a-muchos de campo se describe en el documentation. Sólo hacer:

class User(models.Model): 
    username = models.CharField(max_length=999) 
    password = models.CharField(max_length=999) 
    created_on = models.DateField(auto_now = False, auto_now_add = True) 
    updated_on = models.DateField(auto_now = True, auto_now_add = False) 
    friends = models.ManyToManyField('self') 

Sólo tiene que utilizar through si desea añadir campos adicionales a la relación. Otra descripción de todas las posibilidades se describe en this section.

Como nombras a tu modelo Usuario, supongo que no estás utilizando la compilación en el marco de autenticación. Pero si lo usa, no tiene que implementar la autenticación usted mismo, así que piénselo.

Actualización: ¿Has leído las secciones que he vinculado? Allí se describe:

Hay algunas restricciones en el modelo intermedio:

  • Su modelo intermedio debe contener uno - y sólo uno - clave externa para el modelo de destino (esto sería Persona en nuestro ejemplo). Si tiene más de una clave externa, se generará un error de validación.
  • Su modelo intermedio debe contener una, y solo una, clave externa para el modelo fuente (esto sería Grupo en nuestro ejemplo). Si tiene más de una clave externa, se generará un error de validación.
  • La única excepción a esto es un modelo que tiene una relación de varios a sí mismo, a través de un modelo intermediario. En este caso, se permiten dos claves foráneas para el mismo modelo, pero se tratarán como los dos lados (diferentes) de la relación de muchos a muchos.
  • Al definir una relación de varios a varios de un modelo a sí mismo, utilizando un modelo de intermediario, debe usar symmetrical=False (consulte el model field reference).
+0

He actualizado el ejemplo con su modificación. Sin embargo, todavía necesito la mesa extra para guardar los datos. – dotty

+0

@dotty: Actualicé mi respuesta. –

+1

hmm, he actualizado mi modelo, pasa la validación bien. He agregado un par de Usuarios. y creó un objeto PendingFriendship en el modelo del usuario A.Esto agrega la amistad bien, sin embargo, el objeto del usuario b no obtiene el otro lado de la amistad (porque el valor "simétrico" es falso). Sin embargo, quiero que la relación sea simétrica. ¿algunas ideas? – dotty

0

This blog explica lo que necesita. Desde el blog, simplemente tiene que cambiar related_name en esta línea:

pendingFriends = models.ManyToManyField('self', through='PendingFriendship', symmetrical=False, related_name='friend_requested') 

en:

related_name='friend_requested+' 

Sin embargo, todavía no puedo conseguir que funcione la creación de la relación simétrica de forma automática.

Cuestiones relacionadas