Creating a Many-to-Many relationship
In Django, a many-to-many relationship allows each instance of a model to be associated with multiple instances of another model, and vice versa. For this example, we'll create a Book
, Author
, and Genre
model. A book can have multiple authors and belong to multiple genres. Let's dive in! π
Step 1: Define Your Models π
We'll define three models: Book
, Author
, and Genre
. Each book can have multiple authors and genres.
models.py
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=255)
birth_date = models.DateField(null=True, blank=True)
def __str__(self):
return self.name
class Genre(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=255)
authors = models.ManyToManyField(Author, related_name='books')
genres = models.ManyToManyField(Genre, related_name='books')
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return self.title
Step 2: Create Views to Display Data π
Next, we'll create views to display our Book
data, including its authors and genres.
views.py
from django.shortcuts import render, get_object_or_404
from .models import Book, Author, Genre
def book_detail(request, book_id):
book = get_object_or_404(Book, id=book_id)
return render(request, 'book_detail.html', {'book': book})
def book_list(request):
books = Book.objects.all()
return render(request, 'book_list.html', {'books': books})
def author_list(request):
authors = Author.objects.all()
return render(request, 'author_list.html', {'authors': authors})
def genre_list(request):
genres = Genre.objects.all()
return render(request, 'genre_list.html', {'genres': genres})
Step 3: Define URLs to Access Views π
We'll add URLs to access the list of books, authors, and genres, as well as their details.
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('book/<int:book_id>/', views.book_detail, name='book_detail'),
path('books/', views.book_list, name='book_list'),
path('authors/', views.author_list, name='author_list'),
path('genres/', views.genre_list, name='genre_list'),
]
Step 4: Create Templates for Display π¨
We'll create templates to beautifully display our data.
templates/book_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Book Detail</title>
</head>
<body>
<h1>π Book Detail</h1>
<h2>{{ book.title }}</h2>
<p>π° Price: ${{ book.price }}</p>
<p>βοΈ Authors:</p>
<ul>
{% for author in book.authors.all %}
<li>{{ author.name }}</li>
{% endfor %}
</ul>
<p>π Genres:</p>
<ul>
{% for genre in book.genres.all %}
<li>{{ genre.name }}</li>
{% endfor %}
</ul>
<a href="{% url 'book_list' %}">π Back to Book List</a>
</body>
</html>
templates/book_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Book List</title>
</head>
<body>
<h1>π Book List</h1>
<ul>
{% for book in books %}
<li>
<a href="{% url 'book_detail' book.id %}">
{{ book.title }}
</a>
</li>
{% endfor %}
</ul>
</body>
</html>
templates/author_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Author List</title>
</head>
<body>
<h1>ποΈ Author List</h1>
<ul>
{% for author in authors %}
<li>{{ author.name }}</li>
{% endfor %}
</ul>
</body>
</html>
templates/genre_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Genre List</title>
</head>
<body>
<h1>π Genre List</h1>
<ul>
{% for genre in genres %}
<li>{{ genre.name }}</li>
{% endfor %}
</ul>
</body>
</html>
Step 5: Register Models in Admin Panel π οΈ
Finally, we'll register our models in the admin panel to manage them easily.
admin.py
from django.contrib import admin
from .models import Book, Author, Genre
admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Genre)
Wrapping Up π
You've now created a many-to-many relationship in Django with books, authors, and genres. This allows each book to be associated with multiple authors and genres. Displaying this data using beautiful templates makes it easy to manage and view.