Django by Example: Model Relationship Mapping
Django 5.0+
Relational databases are powerful because they relate tables to each other. Django offers a robust API to define these relationships using ForeignKey, OneToOneField, and ManyToManyField. This code example focuses on the fundamental Many-to-One relationship.
Code
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
# A book has one author, but an author can have many books.
# This is a Many-to-One relationship defined by ForeignKey.
author = models.ForeignKey(
Author,
on_delete=models.CASCADE,
related_name='books'
)
published_date = models.DateField()
def __str__(self):
return self.title
# Usage Example:
# tolkien = Author.objects.create(name="J.R.R. Tolkien")
# book = Book.objects.create(title="The Hobbit", author=tolkien)Explanation
Relational databases derive their power from the ability to link tables. The Many-to-One relationship is the most fundamental of these, represented in Django by the ForeignKey. This field resides on the "Many" side (e.g., the Book) and points to the "One" side (e.g., the Author).
Key concepts include:
- Forward Access: Accessing the related object is synchronous and simple (e.g.,
book.author.name). - Reverse Access: Django automatically creates a "Reverse Manager" on the target model. By default, this is
modelname_set(e.g.,author.book_set.all()), but it can be customized using therelated_nameargument. - Database Efficiency: Accessing related objects can lead to the "N+1 query problem". To mitigate this, use
select_related()for ForeignKey relationships to fetch the related data in a single SQL JOIN.
Code Breakdown
15
models.ForeignKey requires the class of the related model as the first argument. If the model is defined later in the file or in another app, you can use a string reference like 'app_name.ModelName'.17
on_delete is a required argument that tells Django what to do with the Book instances if the referenced Author is deleted.18
related_name='books' creates a clean attribute on the Author instance (author.books.all()) instead of the default author.book_set.all(). This makes the code more readable.7, 23
__str__ method. It is highly recommended to define this method for every model. It provides a human-readable representation of the object in the Django Admin and shell.
