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 (0)