Django provides a powerful and flexible way to work with relational databases through its Object-Relational Mapping (ORM). One of the common relationships we encounter in database design is the Many-to-Many relationship. In Django, this relationship is represented using a ManyToManyField.
In this article, we'll explore how to create, read, update, and delete objects of a Django model that includes a Many-to-Many field.
Understanding Many-to-Many Relationships
A Many-to-Many relationship means that each instance of one model can be related to multiple instances of another model and vice versa. For example, consider a scenario where you have Book and Author models. A book can have multiple authors, and an author can write multiple books.
Suppose we are responsible for creating a schema to store users' travel destinations or favorite foods. We will need a model/table to store destination information such as name, address, and month of travel, and another table to store different tags like adventure, pilgrimage, beach, mountain, etc. In this case, We will need a many-to-many relationship between the destination table and the tags table.

Define the Models
Let's start by defining two models: Author and Book. The Book model will have a ManyToManyField to the Author model.
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)
authors = models.ManyToManyField(Author, related_name="books")
def __str__(self):
return self.title
In this example:
- The
Authormodel has a single fieldname. - The
Bookmodel has atitlefield and aManyToManyFieldnamedauthors, which links to theAuthormodel.
Create Objects of A Django Model Having ManyToMany Field
To create objects in the database, we can use Django's ORM.
Creating Authors:
author1 = Author.objects.create(name="Author One")
author2 = Author.objects.create(name="Author Two")
Output

There are several ways to associate a Book with Author objects:
1. Using the add() Method:
book1 = Book.objects.create(title="Book One")
book1.authors.add(author1, author2)
Output

2. Using the set() Method:
The set() method replaces the current set of related objects with a new set.
book2 = Book.objects.create(title="Book Two")
book2.authors.set([author1])
Output

3. Using the create() Method:
We can also create and add an author directly using the create() method:
book3 = Book.objects.create(title="Book Three")
book3.authors.create(name="Author Three")
Output

Read (Retrieve) Objects of A Django Model Having ManyToMany Field
To retrieve objects and their related data, we can use Django’s ORM queries.
Retrieve All Books for an Author
author_books = Author.objects.get(name="Author One").books.all()
for book in author_books:
print(book.title)
Output

Retrieve All Authors for a Book
book_authors = Book.objects.get(title="Book One").authors.all()
for author in book_authors:
print(author.name)
Output

Update Objects of A Django Model Having ManyToMany Field
Updating objects with a Many-to-Many field involves adding or removing related objects.
Adding an Author to a Book
book1 = Book.objects.get(title="Book One")
new_author = Author.objects.create(name="New Author")
book1.authors.add(new_author)
Output

Removing an Author from a Book
book1.authors.remove(author1)
Output

Using the clear() Method:
The clear() method removes all associations with related objects:
book3.authors.clear()
Output

Delete Objects of A Django Model Having ManyToMany Field
Deleting objects with Many-to-Many relationships is straightforward. Deleting a Book or Author does not automatically delete the related objects, but it will remove the associations.
Deleting a Book
book1 = Book.objects.get(title="Book One")
book1.delete()
Deleting an Author
author1 = Author.objects.get(name="Author One")
author1.delete()
Handling Through Model in Django
Django automatically creates an intermediate table to manage the Many-to-Many relationship. However, if we need to add extra fields to this relationship, we can create a custom through model.
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)
authors = models.ManyToManyField(Author, related_name="books", through='BookAuthor')
def __str__(self):
return self.title
class BookAuthor(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
contribution = models.CharField(max_length=100)
def __str__(self):
return f'{self.author.name}_{self.book.title}'
With this setup, we can manage the relationship directly through the BookAuthor model:
BookAuthor.objects.create(author=author1, book=book1, contribution="Co-Author")
Conclusion
Django’s ManyToManyField provides a powerful way to model complex relationships in our application. By understanding how to create, read, update, and delete objects in a model with a Many-to-Many field, we can effectively manage relationships between entities in our database. Whether we're adding authors to books, updating relationships, or managing through models, Django’s ORM offers the tools we need to work efficiently with relational data.