me encontré con un buen artículo discutiendo que hace algún tiempo, los conceptos básicos son los siguientes:
class Person(models.Model):
name = models.CharField(max_length=100)
relationships = models.ManyToManyField('self', through='Relationship',
symmetrical=False,
related_name='related_to+')
RELATIONSHIP_FOLLOWING = 1
RELATIONSHIP_BLOCKED = 2
RELATIONSHIP_STATUSES = (
(RELATIONSHIP_FOLLOWING, 'Following'),
(RELATIONSHIP_BLOCKED, 'Blocked'),
)
class Relationship(models.Model):
from_person = models.ForeignKey(Person, related_name='from_people')
to_person = models.ForeignKey(Person, related_name='to_people')
status = models.IntegerField(choices=RELATIONSHIP_STATUSES)
Tenga en cuenta el signo más al final de related_name. Esto le indica a Django que la relación inversa no debe exponerse. Dado que las relaciones son simétricas, este es el comportamiento deseado, después de todo, si soy amigo de la persona A, entonces la persona A es amiga mía. Django no creará las relaciones simétricas para usted, así que un poco necesita conseguir añadido a los métodos add_relationship y remove_relationship para manejar de forma explícita el otro lado de la relación:
def add_relationship(self, person, status, symm=True):
relationship, created = Relationship.objects.get_or_create(
from_person=self,
to_person=person,
status=status)
if symm:
# avoid recursion by passing `symm=False`
person.add_relationship(self, status, False)
return relationship
def remove_relationship(self, person, status, symm=True):
Relationship.objects.filter(
from_person=self,
to_person=person,
status=status).delete()
if symm:
# avoid recursion by passing `symm=False`
person.remove_relationship(self, status, False)
Ahora, cada vez que creamos una relación que va uno manera, su complemento es creado (o eliminado). Dado que las relaciones van en ambas direcciones, simplemente podemos utilizar:
def get_relationships(self, status):
return self.relationships.filter(
to_people__status=status,
to_people__from_person=self)
Fuente: Self-referencing many-to-many through
1 para "por favor me deje" –
Una buena lectura sobre este tema: https://charlesleifer.com/ blog/self-referencing-many-many-through/ – Anto