Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

non_field_errors : ["Expected a list of items but got type "dict"."]

I create realtime chat application using websocket frontend(angular) backend(Django).. I want to store messages in to db(mySql).. when I trying to store message from angular to django.. it give me error:

non_field_errors:
["Expected a list of items but got type "dict"."]

so what is wrong?

model.py

class msg(models.Model):
    name = models.ForeignKey(User, on_delete=models.CASCADE)
    receiver = models.CharField(max_length=20)
    text = models.CharField(max_length=1200)
    myDate = models.DateTimeField()

serializer.py

class MesSerializer(serializers.ModelSerializer):
    name = serializers.SlugRelatedField(many=False, slug_field='name', queryset=User.objects.all())
    class Meta:
        model = msg
        fields = '__all__'

view.py

class msg_list(APIView):
    def get(self, request, format=None):
        mes = msg.objects.all()
        serializer = MesSerializer(mes, many=True)  # convert into JSON
        return Response(serializer.data)

    def post(self, request, formate = None):
        serializer = MesSerializer(data=request.data, many = True) #type list
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)
like image 633
Jessica Avatar asked Sep 05 '25 03:09

Jessica


2 Answers

The trouble is not with the slug. It is that you have used many = True in the view when you pass the data to the serializer, but you are in fact only sending a single message - which is why it is a dict and not a list. Remove that parameter.

def post(self, request, formate = None):
    serializer = MesSerializer(data=request.data)
like image 126
Daniel Roseman Avatar answered Sep 07 '25 20:09

Daniel Roseman


I recently came across a problem which is similar to the OP. Hence would like to share my experience and solution.

I have a dictionary of items, each of them unique. I wanted to use PUT to update an existing item. So I used objects.filter to fetch the object based on the name passed via JSON Request(I know I should have used pk, but I didn't because the items are unique and will remain so). Then I created a Django REST Serializer class object to save the updated object but I failed. This is because I wasn't using many = True. But when I did use it, I faced another error:

"non_field_errors": [
        "Expected a list of items but got type \"dict\"."
    ]

So I finally removed both many=True as well objects.filter. Instead I used objects.get. This solved the problem because objects.get returns the required object which I want to update whereas objects.filter returns a queryset object and not the actual object that I want to update. Of course objects.get will fail if I have multiple results, in which case I need to ensure there is a pk. Then again in my case objects.get will never return more than one object.

Hope this post helps someone and saves a lot of their time. :-)

like image 30
AwsAnurag Avatar answered Sep 07 '25 21:09

AwsAnurag