Django: How to Represent and Query Symmetrical Relationships for a Family Tree?

I am building a family tree application in Django where I need to represent and query marriages symmetrically. Each marriage should have only one record, and the relationship should include both partners without duplicating data. Here's the relevant model structure:

class Person(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    spouses = models.ManyToManyField(
        'self', through="Marriage", symmetrical=True, related_name="partners"
    )
    

class Marriage(models.Model):
    person1 = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="marriages_as_person1")
    person2 = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="marriages_as_person2")
    start_date = models.DateField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)

I want to:

  1. Ensure both partners appear as spouses for each other symmetrically.
  2. Avoid duplicate entries for the same marriage.
  3. Efficiently query all spouses of a person.

Here’s the code I’m using to query spouses:

# Query spouses for a person
p1 = Person.objects.create()
p2 = Person.objects.create()
Marriage.objects.create(person1=p1, person2=p2)

p1.spouses.all()   # Returns list containing p2
p2.spouses.all()   # Returns empty list

However, I’m facing challenges:

  1. If p1 spouses are queried, it should contain p2 and if p2 spouses are queried, it should contain p1
  2. Both queries are not symmetrical

Questions:

  1. Is my model structure correct for representing marriages symmetrically? If not, what improvements should I make?
  2. How can I efficiently query all spouses of a person in a database-optimized way while ensuring symmetry?
Вернуться на верх