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:
- Ensure both partners appear as spouses for each other symmetrically.
- Avoid duplicate entries for the same marriage.
- 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:
- If
p1
spouses are queried, it should containp2
and ifp2
spouses are queried, it should containp1
- Both queries are not symmetrical
Questions:
- Is my model structure correct for representing marriages symmetrically? If not, what improvements should I make?
- How can I efficiently query all spouses of a person in a database-optimized way while ensuring symmetry?