Reputation: 3102
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?
Upvotes: 5
Views: 4622
Reputation: 12032
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.
Upvotes: 6
Reputation: 477794
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.
Upvotes: 6