DEV Community

guzmanojero
guzmanojero

Posted on

Understanding related_name in Django (With Clear Examples)

When working with Django models, you’ll eventually need to link one model to another using a ForeignKey, OneToOneField, or ManyToManyField.

At that point, you’ll see an option called related_name.

What is it?

It’s used to give Django a reverse lookup name - the name you use to access all the related objects from the other side of the relationship.

Here’s the idea:

Whenever you define a relationship in Django, you automatically get two ways to access data:

  • Forward access → from the model that declares the field

  • Reverse access → from the other model back to this one

The related_name option controls that reverse access.

1. Without related_name

We have this example:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
Enter fullscreen mode Exit fullscreen mode

If from book you want to get the author, you would do a forward access:
book.author.

But if you want to the get the book from the author, that is a reverse access: author.book_set.all()

Django auto-generates the name book_set.
Functional? Yes.
Pretty? No.


2. With related_name

Let’s give the reverse relation a meaningful name:

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(
        Author,
        on_delete=models.CASCADE,
        related_name="books", # New line
    )
Enter fullscreen mode Exit fullscreen mode

Now the reverse lookup becomes: author.books.all().

3. When related_name Becomes Required

When a model has more than one ForeignKey, OneToOneField, or ManyToManyField pointing to the same other model, you must define related_name for at least one of these relationships.

This is because Django automatically generates a default related_name (e.g. book_set) for reverse access, and if multiple relationships point to the same model, these default names would clash.

4. Disabling the Reverse Relationship

If you don’t want a reverse lookup at all: related_name="+"

class Log(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="+")
Enter fullscreen mode Exit fullscreen mode

Final Takeaway

related_name gives you control over how you access related objects from the other side of a relationship.

Use it when:

  • You want a cleaner API (author.books.all() vs author.book_set.all())
  • You have multiple foreign keys to the same model
  • You want to disable reverse access entirely

It’s a small feature that makes your codebase far more readable.

Top comments (2)

Collapse
 
duncan_true profile image
Dun

This is such a clear, well-structured explanation of related_name! The examples are spot on and make reverse relationships feel intuitive instead of magical. Fantastic job breaking this down so cleanly!

Collapse
 
guzmanojero profile image
guzmanojero

Thanks for the bot comment