Django auto asimétrico a través de la consulta de relación.

Tengo los siguientes – modelos simplificados –

class User(models.Model): following = models.ManyToManyField("self", through='Following', symmetrical=False) class Following(models.Model): from_user = models.ForeignKey(User, related_name='from_user') to_user = models.ForeignKey(User, related_name='to_user') status = models.IntegerField() 

El estado es 0 para pendiente, 1 para siguiente Permitir que el usuario sea un usuario. Me gustaría obtener todos los usuarios de usuario seguidos

puedo hacer

 user.following.all() 

para obtener todos los usuarios que el usuario está siguiendo (relaciones pendientes O realmente seguir)

o

 Following.objects.filter(from_user=user, status=1) 

para obtener todos los siguientes objetos con usuario usuario y amistad real

Pero, ¿cómo puedo obtener todos los objetos Usuario para usuario y estado = 1? Parece que no puedo encontrar una manera

Gracias !

Tratar

 user.following.filter(to_user__status=1) 

el user.following El user.following sigue user.following consultas en el User , por lo que debe abarcar la relación w / __ para Follow aquí.

Los dos campos aquí, from_user y to_user , son ForeignKey apuntan al modelo de User . Así, para una instancia de User() u :

  • u.following búsquedas de los User() s User() que tienen relación w / u través de la tabla intermedia, Follow . La clave aquí es que u.following selecciona la primera ForeignKey en el Follow que apunta al User , como la referencia a u mismo. Por lo tanto, para su versión de Follow , los u.following.filter(to_user__status=1) en los elementos Follow que tienen from_user es igual a u y to_user w / status es igual a 1 . La búsqueda es típica siguiendo la relación hacia atrás.
  • u.from_user busca en la tabla intermedia aquellos que tienen from_user igual a u
  • u.to_user busca en la tabla intermedia aquellos que tienen to_user igual a u

Además, puede filtrar directamente en la ForeignKey , recordando que el from_user y el to_user son ambos la referencia:

 User.objects.filter(to_user__from_user=user, to_user__status=1) # user as from_user User.objects.filter(from_user__to_user=user, from_user__status=1) # user as to_user User.objects.filter(following=user) # those who are followed by `to_user` user 

Parece que

 user.following.filter(to_user__status=1) 

Hace el truco. ¿Puede alguien explicarme por qué y cómo funciona esto? user.following es un ManyRelatedManager que está consultando en User. ¿Qué haría user.following.filter(from_user__status=1) ? No puedo adivinar lo que vuelve … ¡Gracias de nuevo!