Developers working with Django REST Framework (DRF) often encounter serialization issues when handling nested objects or ManyToMany relationships in APIs. One of the common errors is: “{“non_field_errors”: [“Expected a list of items but got type “dict”.”]}”. This error typically arises when DRF expects a list of items but instead receives a dictionary.

Command line execution

Terminalbash
sed by incorrect serializer definitions or request payload structure  is the first step toward solving it. How to Fix the “Expected a List of Items but Got Type Dict” Error? Consider a  ManyToMany relationship  where an  Author  can have multiple  Books , as defined in  models.py : from django.db import models class Book(models.Model):     title = models.CharField(max_length=255) class Author(models.Model):     name = models.CharField(max_length=255)     books = models.ManyToManyField(Book) In the corresponding  serializers.py , using a  nested serializer  without setting  many=True  will cause the error: from rest_framework import serializers from .models import Book, Author class BookSerializer(serializers.ModelSerializer):     class Meta:         model = Book         fields = '__all__' class AuthorSerializer(serializers.ModelSerializer):     books = BookSerializer()     class Meta:         model = Author         fields = '__all__' If an API request is made with the following payload: {     "name": "John Doe",     "books": {"title": "Django for Beginners"} } DRF will return the error  “Expected a list of items but got type “dict”.”  because  books  is a  ManyToManyField  and expects a list. Correcting the Serializer to Accept a List of Items To allow multiple books for an author, modify  books  in the  AuthorSerializer  by adding  many=True : class AuthorSerializer(serializers.ModelSerializer):     books = BookSerializer(many=True)     class Meta:         model = Author         fields = '__all__' Now, when making an API request, ensure the payload sends  books  as a  list of objects : {     "name": "John Doe",     "books": [         {"title": "Django for Beginners"},         {"title": "Advanced Django"}     ] } This modification ensures that Django correctly  processes multiple book instances  without triggering the error. Handling ManyToMany Relationships with Primary Keys Instead of Nested Objects If the API should accept  only book IDs instead of full objects , use the  PrimaryKeyRelatedField  instead of a nested serializer: class AuthorSerializer(serializers.ModelSerializer):     books = serializers.PrimaryKeyRelatedField(queryset=Book.objects.all(), many=True)     class Meta:         model = Author         fields = '__all__' With this change, the API request should send  only book IDs instead of full objects : {     "name": "John Doe",     "books": [1, 2] } This approach is more  efficient for large datasets  where book details  do not need to be sent with the request . Common Issues and Troubleshooting 1. Error Persists Even After Adding  many=True ✔ Ensure that the API request payload correctly sends  a list of objects  instead of a dictionary. ✔ Double-check that  many=True  is applied  only for ManyToMany relationships  and  not for ForeignKey fields . ✔ Restart the Django server after modifying serializers to ensure changes are applied. 2. Unable to Save Nested Data for ManyToMany Relationships ✔ Overriding the  create()  method ensures that nested objects are  properly created : class AuthorSerializer(serializers.ModelSerializer):     books = BookSerializer(many=True)     class Meta:         model = Author         fields = '__all__'     def create(self, validated_data):         books_data = validated_data.pop('books')         author = Author.objects.create(**validated_data)         for book_data in books_data:             book, created = Book.objects.get_or_create(**book_data)             author.books.add(book)         return author ✔ This allows new books to be  created and associated  with the author dynamically. 3. Using a ForeignKey Instead of ManyToMany But Still Facing the Error ✔ Many developers mistakenly apply  many=True  to  ForeignKey fields , causing unintended errors. ✔ ForeignKey relationships expect a  single dictionary , whereas ManyToMany relationships require  lists of dictionaries . class ChapterSerializer(serializers.ModelSerializer):     book = serializers.PrimaryKeyRelatedField(queryset=Book.objects.all())     class Meta:         model = Chapter         fields = '__all__' ✔ The request should send only a single book ID: {     "title": "Chapter One",     "content": "Introduction to Django",     "book": 1 } Why Understanding Serializer Structures in DRF is Important? 🔹 Ensures data consistency and prevents serialization errors when handling nested relationships. 🔹 Helps developers optimize API requests, reducing payload size and improving performance. 🔹 Allows flexible data structures, enabling APIs to handle both nested and primary key-based relationships effectively. 🔹 Prevents common Django REST Framework mistakes, improving overall backend efficiency. By structuring serializers correctly and sending API requests in the expected format, developers can avoid erro

Risk level: destructive. Review the command before running it.

Implementation details

Understanding why this happens and how to fix it ensures smoother API development and prevents data serialization issues. Understanding the Error: Why Does Django REST Framework Expect a List? 🔹 Django REST Framework serializers are designed to handle different types of data structures, including single objects, lists of objects, and nested relationships. 🔹 When using a ManyToManyField or ForeignKey with a nested serializer, DRF expects a list of objects for ManyToMany fields but a dictionary for ForeignKey fields. 🔹 If the API receives a dictionary instead of a list where a ManyToMany field is expected, it triggers the error: “Expected a list of items but got type “dict”.” 🔹 This issue commonly occurs when working with nested serializers, bulk data submissions, or incorrect request payload formatting.

Gotchas and common issues

  • Permission checks - verify user access rights and sudo privileges before executing system-level operations.

  • Environment configuration - double-check path variables and dependency versions to prevent runtime failures.

  • Backup safeguards - maintain configuration backups before applying system or database modifications.

Following these steps ensures clean configuration and reliable execution for solved: {“non_field_errors”: [“expected a list of items but got type “dict”.”]}.