Open In App

How to Express a One-To-Many Relationship in Django?

Last Updated : 03 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In Django, expressing relationships between models is crucial to structuring our database. One of the most common relationships is One-To-Many, where a single record in one model is associated with multiple records in another model. For example, an author can write multiple books, but each book is written by a single author.

In this article, we will cover the fundamentals of the One-To-Many relationship in Django, including how to express it using the ForeignKey field, creating a Django project, and working with data in the Django shell.

What is a One-To-Many Relationship?

A One-To-Many relationship means that one entity can be related to many others. In Django, this is achieved using a ForeignKey field. This field defines a link between two models, and allows multiple records from one model to refer to a single record in another.

For example:

  • One Author can write many Books.
  • Each Book is linked to one Author.

This relationship is ideal for use cases like:

  • One company having many employees.
  • One blog post having many comments.
  • One category containing many products.

Defining One-To-Many Relationship in Django

Let’s create a Django project where we will model a One-To-Many relationship between an Author and their Books.

Step 1: Set Up a Django Project

Create a new Django project and app:

django-admin startproject book_author_project
cd book_author_project
python manage.py startapp library

Register the library app in settings.py:

Python
INSTALLED_APPS = [
    # Other apps
    'library',
]

Step 2: Define Models for One-To-Many Relationship

In the models.py of the library app, define two models: Author and Book.

Explanation of ForeignKey Field:

  • ForeignKey: This field creates a relationship where each instance of the Book model references a single Author.
    • on_delete=models.CASCADE: If the referenced Author is deleted, all related Book records will be deleted as well.
    • related_name='books': This gives a reverse relation from Author to Book, meaning you can access all books written by an author using author.books.all().
Python
from django.db import models

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

    def __str__(self):
        return self.name

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

    def __str__(self):
        return self.title

Step 3: Apply Migrations

Run the following commands to create the necessary database tables for the Author and Book models:

python manage.py makemigrations
python manage.py migrate

This will create the necessary database tables for your models and establish the One-To-Many relationship using the ForeignKey field.

Step 4: Create Data in Django Shell

Now, let’s use the Django shell to create data and work with the One-To-Many relationship.

Open the Django shell:

python manage.py shell

Import the Author and Book models and Create a few authors:

Python
from library.models import Author, Book

author1 = Author.objects.create(name="J.K. Rowling")
author2 = Author.objects.create(name="George R.R. Martin")
author3 = Author.objects.create(name="J.R.R. Tolkien")

Create books and associate them with authors:

Python
# Books for J.K. Rowling
book1 = Book.objects.create(title="Harry Potter and the Philosopher's Stone", author=author1)
book2 = Book.objects.create(title="Harry Potter and the Chamber of Secrets", author=author1)

# Books for George R.R. Martin
book3 = Book.objects.create(title="A Game of Thrones", author=author2)
book4 = Book.objects.create(title="A Clash of Kings", author=author2)

# Books for J.R.R. Tolkien
book5 = Book.objects.create(title="The Fellowship of the Ring", author=author3)
book6 = Book.objects.create(title="The Two Towers", author=author3)

Step 5: Querying and Accessing Related Data

Once you’ve set up your One-To-Many relationship, we can use Django’s ORM to easily access related data.

1 . Access All Books by a Specific Author

Use the related_name (books) to access all books by an author.

Python
# Get all books written by J.K. Rowling
author_rowling = Author.objects.get(name="J.K. Rowling")
rowling_books = author_rowling.books.all()

print(rowling_books)

Output:

<QuerySet [<Book: Harry Potter and the Philosopher's Stone>, <Book: Harry Potter and the Chamber of Secrets>]>

2. Access the Author of a Specific Book

We can also access the author of a specific book using the author field.

Python
book = Book.objects.get(title="The Fellowship of the Ring")
print(book.author)

Output:

J.R.R. Tolkien

3. Filtering Books by Author

We can filter books based on the author directly from the Book model.

Python
# Get all books written by George R.R. Martin
martin_books = Book.objects.filter(author=author2)

print(martin_books)

Output:

<QuerySet [<Book: A Game of Thrones>, <Book: A Clash of Kings>]>

Step 6: Deleting Records and the on_delete Behavior

If we delete an author, all of their related books will be deleted due to the on_delete=models.CASCADE behavior.

author2.delete()
# George R.R. Martin and his books (A Game of Thrones, A Clash of Kings) will be deleted.

We can verify this by checking the database:

Python
remaining_books = Book.objects.all()
print(remaining_books)

Output:

<QuerySet [<Book: Harry Potter and the Philosopher's Stone>, <Book: Harry Potter and the Chamber of Secrets>, 
<Book: The Fellowship of the Ring>, <Book: The Two Towers>]>

As expected, George R.R. Martin’s books were deleted along with his record.

errr
Django Shell Output

Conclusion

In this article, we explored how to express a One-To-Many relationship in Django using the ForeignKey field. The ForeignKey field establishes a relationship where one record in a model can be associated with multiple records in another model. Django’s ORM makes it easy to query related data, filter results, and manage relationships with minimal effort.

By following this guide, we can effectively structure relationships between our models, allowing for complex queries and data handling in our Django projects.


Next Article
Practice Tags :

Similar Reads