Difference between 'related_name' and 'related_query_name' attributes in Django?
related_name
will be the attribute of the related object that allows you to go 'backwards' to the model with the foreign key on it. For example, if ModelA
has a field like: model_b = ForeignKeyField(ModelB, related_name='model_as')
, this would enable you to access the ModelA
instances that are related to your ModelB
instance by going model_b_instance.model_as.all()
. Note that this is generally written with a plural for a Foreign Key, because a foreign key is a one to many relationship, and the many side of that equation is the model with the Foreign Key field declared on it.
The further explanation linked to in the docs is helpful. https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects
related_query_name
is for use in Django querysets. It allows you to filter on the reverse relationship of a foreign key related field. To continue our example - having a field on Model A
like:
model_b = ForeignKeyField(ModelB, related_query_name='model_a')
would enable you to use model_a
as a lookup parameter in a queryset, like: ModelB.objects.filter(model_a=whatever)
. It is more common to use a singular form for the related_query_name
. As the docs say, it isn't necessary to specify both (or either of) related_name
and related_query_name
. Django has sensible defaults.
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
Here foreign key forward relation is Album to musician and backward relation is musician to album. This means one album instance can have relation with only one musician instance(forward relation), and one musician instance can relate to multiple album instance(backward).
Forward query will be like this
Album_instance.artist
note here forward query done by Album_instance followed by artist(field name). and backward would be
Musician_instance.album_set.all()
here for backward query modelname_set is used .
now if you specifies the related_name like
artist = models.ForeignKey(Musician, on_delete=models.CASCADE, related_name='back')
then backward query syntax will be change modelname_set(artist.set) will be replace by back. now backward query
Musician_instance.back.all()
If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'.
and related_query_name to use for the reverse filter name from the target model