13

In the Django documentation about related_name it says the following:

The name to use for the relation from the related object back to this one. It’s also the default value for related_query_name (the name to use for the reverse filter name from the target model). See the related objects documentation for a full explanation and example. Note that you must set this value when defining relations on abstract models; and when you do so some special syntax is available.

If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'.

I didn't understand it clearly. If somebody would please explain it a bit more, it would help me a lot.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Rrakib
  • 200
  • 1
  • 1
  • 9
  • 1
    This seems a bit broad. What exactly about this - and the linked documentation - don't you understand? – Daniel Roseman May 24 '17 at 14:15
  • Why it is used and where it is used and what's about the '+' sign? – Rrakib May 24 '17 at 14:17
  • 1
    But those are the things that are explicitly explained in the paragraphs you quote. – Daniel Roseman May 24 '17 at 14:21
  • 1
    Actually I'm new in django and it is hard to understand(probably because I'm dumb). So, I thought if I asked here some expertise would break the paragraph a bit and explain a bit more about "relation from the related object back to this one" and "+" sign. – Rrakib May 24 '17 at 14:26
  • That's the name you need to call from a related object in order to get it's parent-related model object(s) – Kostas Livieratos May 24 '17 at 14:34

2 Answers2

25

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.

Anonymous
  • 11,740
  • 3
  • 40
  • 50
16
  1. 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 field

    class 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 to Article). After defining this you can retrieve the articles of an user like so:

    author.articles.all()
    
  2. 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()
    
  3. 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 the ForeignKey field is defined) you can set

    class Author(models.Model):
        author = models.ForeignKey(User, related_name='+')
    
doru
  • 9,022
  • 2
  • 33
  • 43