Reverse Relationships

In Django, you can define reverse relationships to access related objects from the reverse side of a ForeignKey or ManyToManyField relationship. Let's create a simple example using the Author and Book models to demonstrate reverse relationships.

1. Create the Author and Book models:

from django.db import models

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

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

In this example:

  • We have two models: Author and Book.

  • Each Book has a foreign key relationship with an Author, meaning each book is authored by a specific author.

2. Create and retrieve Author and Book objects:

# Create authors
author1 = Author.objects.create(name="J.K. Rowling")
author2 = Author.objects.create(name="George Orwell")

# Create books by associating them with authors
book1 = Book.objects.create(title="Harry Potter and the Sorcerer's Stone", author=author1)
book2 = Book.objects.create(title="1984", author=author2)
book3 = Book.objects.create(title="Harry Potter and the Chamber of Secrets", author=author1)

# Access books by a specific author using the reverse relationship
books_by_rowling = author1.book_set.all()

# Print the titles of books by J.K. Rowling
for book in books_by_rowling:
    print(f"Book by J.K. Rowling: {book.title}")

In this code:

  • We create two authors, J.K. Rowling and George Orwell, and three books associated with these authors.

  • To access the books written by a specific author (in this case, J.K. Rowling), we use the book_set attribute, which is automatically generated by Django for the reverse relationship from Author to Book.

  • We then loop through the books written by J.K. Rowling and print their titles.

The book_set attribute allows you to access the related Book objects for a specific Author. You can also define a related_name on the ForeignKey to provide a custom name for the reverse relationship if you prefer not to use the default modelname_set.

Last updated