What does related_name do?
If in a model you have a
ForeignKey
field (this means you point through this field to other model):class Author(models.Model): name = ...... email = ..... class Article(models.Model): author = models.ForeignKey(Author) title= .... body = ....
if you specify
related_name
on this fieldclass Article(modles.Model): author = models.ForeignKey(Author, related_name='articles')
you give a name to the attribute that you can use for the relation (named reverse realationship) from the related object back to this one (from
Author
toArticle
). After defining this you can retrieve the articles of an user like so:author.articles.all()
If you don't define a
related_name
attribute, Django will use the lowercase name of the model followed by_set
(that is, in our case,article_set
) to name the relationship from the related object back to this one, so you would have to retrieve all articles of an user like so:author.article_set.all()
If you don't want to be possible a reverse relationship (from the model to which points your
ForeignKey
filed to this model (the model in which theForeignKey
field is defined) you can setclass Author(models.Model): author = models.ForeignKey(User, related_name='+')
When you create a foreign key, you are linking two models together. The model with the ForeignKey()
field uses the field name to look up the other model. It also implicitly adds a member to the linked model referring back to this one.
class Post(models.Model):
# ... fields ...
class Comment(models.Model):
# ... fields ...
post = models.ForeignKey(Post, related_name=???)
There are three possible scenarios here:
1. Don't specify related_name
If you don't specify a name, django will create one by default for you.
some_post = Post.objects.get(id=12345)
comments = some_post.comment_set.all()
The default name is the relation's name + _set
.
2. Specify a custom value
Usually you want to specify something to make it more natural. For example, related_name="comments"
.
some_post = Post.objects.get(id=12345)
comments = some_post.comments.all()
3. Prevent the reverse reference from being created
Sometimes you don't want to add the reference to the foreign model, so use related_name="+"
to not create it.
some_post = Post.objects.get(id=12345)
comments = some_post.comment_set.all() # <-- error, no way to access directly
related_query_name
is basically the same idea, but when using filter()
on a queryset:
posts_by_user = Post.objects.filter(comments__user__id=123)
But to be honest I've never used this since the related_name
value is used by default.