According to the documentation, related names must be unique. Again according to the documentation the default value, (if not set explicitly by the developer) is FOO_set
, where FOO
is the source model name.
So if I have two foreign keys (pointing to two different models, of course), wouldn't the (default) related names be similar?
The related_name attribute specifies the name of the reverse relation from the User model back to your model. If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix _set, for instance User.
Using the related_name allows you to specify a simpler or more legible name to get the reverse relation. In this case, if you specify user = models.
One to many relationships in Django models. To define a one to many relationship in Django models you use the ForeignKey data type on the model that has the many records (e.g. on the Item model). Listing 7-22 illustrates a sample of a one to many Django relationship.
The on_delete method is used to tell Django what to do with model instances that depend on the model instance you delete. (e.g. a ForeignKey relationship). The on_delete=models. CASCADE tells Django to cascade the deleting effect i.e. continue deleting the dependent models as well.
I'd like to extend the excellent answer of Willem Van Onsem. In his example the class C is related to the classes A and B. Therefore A and B have attributes c_set
, but they are different classes. Thus the attributes c_set
, which have the same name, exist in a different scope (namespace).
But what if the relation is of different nature. Let's take a look at different example. Imagine an application for sport teams. We have classes Person and Team. A person can play for a team or coach a team. The models would look like:
class Person(models.Model):
name = models.CharField(max_length=255, unique=True)
class Team(models.Model):
name = models.CharField(max_length=255, unique=True)
place = models.CharField(max_length=255)
players = models.ManyToManyField('Person')
coaches = models.ManyToManyField('Person')
Now this should create an attribute team_set
to the class Person:
person = Person.objects.get(pk=1)
# now we want to get the teams where the person participates
person.team_set.all()
And there is the problem! Which relation should be used - players
or coaches
? Django won't allow this and ask for explicit declaration of related names.
We can fix the problem by declaring the related names, for example:
players = models.ManyToManyField('Person', related_name='plays_in_teams')
coaches = models.ManyToManyField('Person', related_name='trains_teams')
After this change we can query the teams like:
person.plays_in_teams.all()
person.trains_teams.all()
This shows the usefulness of related names. They help to create human readable queries and increase the maintainability of the code.
Given you have a model C
, with ForeignKey
s to A
and B
, like:
class A(models.Model):
pass
class B(models.Model):
pass
class C(models.Model):
a = models.ForeignKey(A, on_delete=models.CASCADE)
b = models.ForeignKey(B, on_delete=models.CASCADE)
Then there are indeed two c_set
s, but these are on different models. So A
objects have a c_set
, and B
objects have a c_set
, but there is no confusion, since the type of object determines about which relation we are talking.
Frequently it makes sense however to specify a related_name=...
, parameter with better nomenclature.
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