[Solved]-Why use "through" argument for ManyToManyField in Django models?


I think you’re thinking a little too literally about this. Let’s say you didn’t use through:

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person)

    def __unicode__(self):
        return self.name

Django, behind the scenes, essentially creates the following model for you:

class GroupPerson(models.Model)
    group = models.ForeignKey(Group)
    person = models.ForeignKey(Person)

The reason for creating a Membership model is to add extra data that the default model Django automatically creates wouldn’t have by default, but since you’re no longer using the default, you have to tell Django that, using through. Basically, you’re preserving the API Django provides for ManyToManyFields.


The reason why one would do this is so that Group has a field for this relationship, rather than having to follow the relationship back through its membership_set.

If nothing else, this can make writing queries simpler. At the very least, this can make a programmer’s life easier, and code easier to read. A sufficiently optimising ORM would be able to generate appropriate indices to speed up such access (and unless I’m very much mistaken, django does indeed do that; or at least South does).



It’s so that, from Group, you can directly access the members. You don’t necessarily want to deal with Membership objects directly (the user my never even see them). You just want groups with some extra information stored. Think of Membership as meta-data on the association between Person and Group.


through tables are used to store properties of the relation, in this case, e.g. the date a Person joined a particular Group


Leave a comment