[Django]-In Django, what does symmetrical=True do?

17👍

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.

👤AKS

37👍

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

4👍

Symmetrical relationship

class User(models.Model)
...
    friends = models.ManyToManyField("self")
...
alice = User()
bob = User()
bob.friends.add(alice)

Now, Bob is an Alice’s friend and Alice is a Bob’s friend

Non symmetrical relationship

class User(models.Model)

     ...
     parents = models.ManyToManyField("self", symmetrical=False)
 ...
 alice = User()
 bob = User()
 bob.parent.add(alice)

Now, Alice is a Bob’s parent, but Bob isn’t an Alice parent.

Original answer: https://stackoverflow.com/a/34998422/5993109

Leave a comment