In Django, what does symmetrical=True do?

Here is what is says in the documentation:

Only used in the definition of ManyToManyFields on self. Consider the following model:

from django.db import models
class Person(models.Model):
    friends = models.ManyToManyField("self")

When Django processes this model, it identifies that it has a ManyToManyField on itself, and as a result, it doesn’t add a person_set attribute to the Person class. Instead, the ManyToManyField is assumed to be symmetrical – that is, if I am your friend, then you are my friend.

By default, the value of symmetrical is True for Many to Many Field which is a bi-directional relationship.

Using a through table (symmetrical=False):

But you can also imagine a situation where you don't need this type of relationship so you can add symmetrical=False. And, this can be achieved by using a through table because by default symmetrical is False if you use a through table:

Recursive relationships using an intermediary model are always defined as non-symmetrical – that is, with symmetrical=False – therefore, there is the concept of a “source” and a “target”. In that case 'field1' will be treated as the “source” of the relationship and 'field2' as the “target”.

So you can imagine a situation where you do need the direction i.e. let's say there is a Node model and it has a relationship with itself using a through table. If we didn't have the requirement of direction here we could go with the example shown earlier. But now we also need a direction from one node to another where one being source and another one being target and due to nature of this relationship it cannot be symmetrical.


Let's say you have two instances of Contact, John and Judy. You may decide to make John a contact of Judy. Should this action also make Judy a contact of John? If so, symmetrical=True. If not, symmetrical=False