Search code examples
djangomongodbdjango-modelsdjango-serializerdjongo

“non_field_errors”: [ “Invalid data. Expected a dictionary, but got QuerySet.” ] problem with serializer or model from djongo


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.

the error message from django REST framework api

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.


Solution

  • Checking if the serializer is valid makes no sense. You here use this to convert a queryset of objects to serialized data, not the other way.

    You serialize the data with:

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

    You should not work with .values(…), since this will erode the logic in the model layer and return only dictionaries.


    Note: Functions are normally written in snake_case, not PascalCase, therefore it is advisable to rename your function to get_orders, not getOrders.