Search code examples
djangodjango-modelspython-3.5django-1.10

Django Reverse relationship with Recursive M2M Relationship


Trying to expand from the documentation in here : https://docs.djangoproject.com/en/1.10/topics/db/models/#extra-fields-on-many-to-many-relationships

The context makes it easier to understand, Person object, M2M relationship with itself that defines 'relationship types' between two Persons, like Parent/Child/Engaged

My Models.py :

RELATIONSHIPS = (

    (0, 'Child'),
    (1, 'Parent'),
    (2, 'Engaged'),
)

class Person(models.Model):
    code = models.AutoField(primary_key=True, verbose_name="Person Code")
    name = models.CharField(max_length=150, blank=True, null=True, verbose_name="Name")

    relationships = models.ManyToManyField(
        'self', 
        through = 'Person_Person', #This lets you define the model that will act as an intermadiary
        symmetrical = False, #This needs to be set with recursive relationships
        )

class Person_Person(models.Model):
    person_1 = models.ForeignKey('Person', on_delete=models.CASCADE, 
        related_name='%(class)s_person_1', verbose_name="Person 1")
    person_2 = models.ForeignKey('Person', on_delete=models.CASCADE,
        related_name='%(class)s_person_2', verbose_name="Person 2")
    relationship_type = models.IntegerField(choices = RELATIONSHIPS, default = 5, verbose_name="Relation")

Test code :

p1 = Person.objects.create(name = 'Man')
p2 = Person.objects.create(name = 'Woman')

relation = Person_Person(person_1 = p1, person_2 = p2, relationship_type = 2)
reation.save()

print(p1.relationships.all(), p2.relationships.all())
#>><QuerySet [<Person: 108 Woman>]>
#>><QuerySet []>

Now for the problem, p2's queryset for the relationships field returned empty, I understand why when you think about a non-recursive relationship, but in this case calling p2.relationships_set makes no sense, even if it did, how would I know a Person is the person_1 or person_2 of the relationship?

Any suggestion is welcome


Solution

  • This seems to be a duplicate of How to make recursive ManyToManyField relationships that have extra fields symmetrical in Django? but i cant mark them

    Basicly this is not possible in django as you have to define symmetrical=False. You have the option to add a second m2m field for the other way around. The other thread has some good reads about that