How to add to manytomany field in Django

Adding to a ManyToMany field in Django is quite straightforward and offers a few different ways to achieve it, depending on your needs. The key is that ManyToMany relationships don’t directly store the related objects on the “many” side; instead, they manage an intermediate table.

Let’s assume you have two models, Book and Author, with a ManyToMany relationship:


# models.py
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')
    published_date = models.DateField()

    def __str__(self):
        return self.title
            

Now, let’s look at how to add authors to a book (or books to an author, the methods are symmetrical). We’ll work with instances of these models.

1. Adding a Single Object

The most common way to add a single related object is using the add() method of the ManyToMany manager.


# Assuming you have Author and Book instances
from myapp.models import Author, Book

# Create some instances if you don't have them
author1 = Author.objects.create(name='Jane Doe')
author2 = Author.objects.create(name='John Smith')
book1 = Book.objects.create(title='The Great Novel', published_date='2023-01-01')

# Add authors to book1
book1.authors.add(author1) # Add Jane Doe to The Great Novel
book1.authors.add(author2) # Add John Smith to The Great Novel

# You can also do it the other way around:
# author1.books.add(book1) # Adds book1 to author1 (assuming 'books' is the related_name)

print(book1.authors.all())
# Output: <QuerySet [<Author: Jane Doe>, <Author: John Smith>]>
            

2. Adding Multiple Objects at Once

You can pass multiple objects (as separate arguments) to the add() method.


from myapp.models import Author, Book

author3 = Author.objects.create(name='Alice Wonderland')
author4 = Author.objects.create(name='Bob Builder')
book2 = Book.objects.create(title='Another Story', published_date='2024-05-15')

# Add multiple authors to book2
book2.authors.add(author3, author4)

print(book2.authors.all())
# Output: <QuerySet [<Author: Alice Wonderland>, <Author: Bob Builder>]>
            

3. Adding Objects from an Iterable (List, QuerySet, etc.)

If you have a list or a QuerySet of objects you want to add, you can unpack them using the * operator or pass them directly as an iterable (Django will unpack them for you).


from myapp.models import Author, Book

author_list = [
    Author.objects.create(name='Charles Dickens'),
    Author.objects.create(name='Leo Tolstoy')
]
book3 = Book.objects.create(title='Classic Tales', published_date='1850-01-01')

# Option A: Unpack the list (explicit)
book3.authors.add(*author_list)

# Option B: Pass the list directly (Django handles unpacking internally)
# book3.authors.add(author_list[0], author_list[1]) # also works if you want to be explicit

print(book3.authors.all())
# Output: <QuerySet [<Author: Charles Dickens>, <Author: Leo Tolstoy>]>

# Adding from a QuerySet
existing_authors_qs = Author.objects.filter(name__contains='Jane') # Assuming Jane Doe exists
book4 = Book.objects.create(title='Modern Reads', published_date='2025-01-01')
book4.authors.add(*existing_authors_qs)

print(book4.authors.all())
# Output: <QuerySet [<Author: Jane Doe>]>
            

4. Adding by Primary Key (ID)

You can also add related objects using their primary keys (IDs), which can be useful if you’re dealing with data from forms or APIs where you only have the IDs.


from myapp.models import Author, Book

# Assuming author IDs 1 and 2 exist (e.g., from previous creations)
book5 = Book.objects.create(title='ID Based Book', published_date='2024-11-01')

# Add by primary keys
book5.authors.add(author1.pk, author2.pk) # using existing author objects' primary keys

# Or directly with known IDs
# book5.authors.add(1, 2) # If you know the IDs

print(book5.authors.all())
# Output: <QuerySet [<Author: Jane Doe>, <Author: John Smith>]>
            

Important Considerations:

  • No Duplicates: The add() method automatically handles duplicates. If you try to add an object that’s already related, it simply won’t be added again, and no error will be raised.
  • Saving the Instance: You don’t need to call book.save() after using add(). Django’s ManyToMany manager handles the database operations directly for the relationship.
  • set() vs. add():
    • add() adds objects to the existing set of related objects.
    • set() replaces the entire set of related objects with the ones you provide. It effectively clears all existing relationships and then adds the new ones.
    
    # Example for set()
    book1.authors.set([author3, author4]) # Now book1 only has author3 and author4, Jane Doe and John Smith are removed.
    print(book1.authors.all())
    # Output: <QuerySet [<Author: Alice Wonderland>, <Author: Bob Builder>]>
                        
  • Removing Relationships:
    • remove(): Removes specific related objects.
    • clear(): Removes all related objects from the ManyToMany relationship for that instance.
    
    book1.authors.remove(author3) # Removes Alice Wonderland from book1
    book1.authors.clear() # Removes all authors from book1
                        
See also  How to Reset ID Sequence in Django