For example:
class Contact(models.Model):
contacts = models.ManyToManyField('self', through='ContactRelationship', symmetrical=False)
What does the symmetrical=False
parameter do?
When should it be left as True
, and when should it be set as False
?
How does this settings affect the database (does it create extra columns etc)?
Fields in Django are the data types to store a particular type of data. For example, to store an integer, IntegerField would be used. These fields have in-built validation for a particular data type, that is you can not store “abc” in an IntegerField.
The through attribute/field is the way you customize the intermediary table, the one that Django creates itself, that one is what the through field is changing.
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
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 aperson_set
attribute to thePerson
class. Instead, theManyToManyField
is assumed to besymmetrical
– 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With