Mojimi Mojimi - 1 year ago 84
Python Question

Django how to populate fields in 'trough' intermediate model when adding an object to a ManyToManyField?

I couldn't word it properly nor could I find it in the documentation, but how do I also add to the intermediate 'through' model of a

when adding new objects to it?

Note that its a recursive relationship, but I used
as I was unsure if
supports a "through" model (the documentation does not specifies it)

will be used regardless of the
field, adding objects like parents/child relationships to it (which have no field in
(This was due to the confusion that ManyToManyField was an actual field in the output table in a SQL relational database)

(I realize that my model has some contextual/theoretical flaws, but let's abstract that for now)

For example :

class Person(models.Model):
objectid = models.AutoField(primary_key=True)
name = models.CharField()
curr_partner = models.ManyToManyField(
on_delete = models.CASCADE,
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, ondelete=models.CASCADE)
person_2 = models.ForeignKey(Person, ondelete=models.CASCADE)
relation = models.ChoiceField(
('P', 'Parent'),
('C', 'Child'),
('E', 'Engaged'),
('W', 'Widow'),

Query :

#Adding a married couple

father = Person(name = "John")
mother = Person(name = "Anna")

father.curr_partner.add( mother , through.relation = "Engaged") #???

#Adding a 'Child' relation

child = Person(name = "Billy")

#This makes sense??
p1 = Person_Person(person1 = father, person2 = child, relation = "Child")
p2 = Person_Person(person1 = mother, person2 = child, relation = "Child")

Answer Source

You create the relationships by saving instances of the relationship's model, like you (almost) did with the children. You'd have something like

father = Person(name = "John")
mother = Person(name = "Anna")

marriage = Person_Person.objects.create(person1=father, person2=mother, relation="E")

p1 = Person_Person.objects.create(person1=father, person2=child, relation="C")
p2 = Person_Person.objects.create(person1 = mother, person2 = child, relation="C")

BTW, your curr_partner attribute doesn't have an accurate name, since it actually denotes all of a person's relationships, not just marriage. Maybe you should rename it to relationships or kindred and have a property to get the person's partner:

def curr_partner(self):
        return self.relationships.objects.get(relation='E')
    except Person_Person.DoesNotExist:
        # No marriage relationship
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download