"non_field_errors": [ "Invalid data. Expected a dictionary, but got QuerySet." ]

I’ve recently started to learn django. And at this time i’m working on integrating mongoDB with Django using djongo driver. I’ve created a model for saving and mapping my data objects to mongoDB but i’m lacking knowledge about implementing serializers and at this stage i’m encountering one situation which i’ve been unable to resolve since 2 days so please throw some light and help me implement it.

models.py

from djongo import models

# Create your models here.

class OrderItem(models.Model):
    
    itemDescription = models.TextField(name = "itemDescription")
    itemQuantity = models.FloatField(name = "itemQuantity")
    itemPrice = models.FloatField(name = "itemPrice")
    
    class Meta:
        abstract = True
    

class Order(models.Model):
    email = models.EmailField(primary_key = True, name = "email") 
    customerName = models.CharField(max_length=30, help_text="Enter Customer Name", name = "customerName")
    customerAddress = models.TextField(help_text="Enter customer's Address", name = "customerAddress")
    
    orderItems = models.ArrayField(
        model_container = OrderItem,
    )
    
    objects = models.DjongoManager()

serializers.py

from .models import Order, OrderItem
from rest_framework.serializers import ModelSerializer

class OrderItemsSerializer(ModelSerializer):
    class Meta:
        model = OrderItem
        fields = '__all__'

class OrderSerializer(ModelSerializer):
    orderItems = OrderItemsSerializer(many=True)
    class Meta:
        model = Order
        fields = "__all__"
   

views.py

@api_view(['GET'])
def getOrders(request):
    
    orders = Order.objects.values()
    serializer = OrderSerializer(data = orders)
    
    if serializer.is_valid():
        print("Valid")
        return Response(data = serializer.data)
    else:
        print("invalid")
        print(serializer.errors)
        return Response(serializer.errors)

and this is my json data which i’ve stored inside my mongodb orders collection.

[
  {
    "email": "himanshu@gmail.com",
    "customerName": "Himanshu Maiyani",
    "customerAddress": "B-4-102, Gadhpur Township",
    "orderItems": [
      {
        "itemDescription": "pencil",
        "itemQuantity": 10,
        "itemPrice": 35.0
      },
      {
        "itemDescription": "books",
        "itemQuantity": 12,
        "itemPrice": 600.0
      },
      {
        "itemDescription": "school bag",
        "itemQuantity": 1,
        "itemPrice": 800.0
      }
    ]
  },
  {
    "email": "jayesh@gmail.com",
    "customerName": "Jayesh Maiyani",
    "customerAddress": "C-1-103, Gadhpur Township",
    "orderItems": [
      {
        "itemDescription": "watch",
        "itemQuantity": 5,
        "itemPrice": 5000.0
      },
      {
        "itemDescription": "earphone",
        "itemQuantity": 2,
        "itemPrice": 995.5
      },
      {
        "itemDescription": "USB cable",
        "itemQuantity": 1,
        "itemPrice": 100.0
      }
    ]
  }
]

please explain where i’m lacking understanding.

On your views.py, your orders variable has the type: <class 'django.db.models.query.QuerySet'>
But, your serializer expects a dict on the data argument. Instead of calling values() use all().
And pass a additional argument to the serializer many=True. So you will end up with something like:

@api_view(['GET'])
def getOrders(request):
    
    orders = Order.objects.all()
    serializer = OrderSerializer(orders, many=True)
    return Response(data = serializer.data)

Also, you don’t need to call .is_valid() when you’re only displaying data from the database. This method is mainly used when you receive external input.
Hope it helps.

thanks @leandrodesouzadev for the quick attention but can you be more precise that how I need to modify my serializer to make it compatible?

please take a note that i’m using ArrayField in my model which is not part of django models and is implemented in djongo.

and yes I tried implementing your solution.
and eneded up with another error.

new views.py

@api_view(['GET',])
def getOrders(request):
    
    orders = Order.objects.all()
    serializer = OrderSerializer(data = orders, many= True)
    return Response(data = serializer.data)

new error message:

Exception Type: AssertionError at /orders/
Exception Value: When a serializer is passed a `data` keyword argument you must call `.is_valid()` before attempting to access the serialized `.data` representation.
You should either call `.is_valid()` first, or access `.initial_data` instead.

I’ve never used Djongo before, but you problem now is related with rest_framework.
You are creating your serializer again using the data argument. Try like this:
serializer = OrderSerializer(instance=orders, many= True)

If that doesn’t work, Maybe you can get a new error message.

1 Like