'In order to allow non-dict objects to be serialized set the safe parameter to False

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 array from angular to django..it give me error like 500 internal server Eroor and In order to allow non-dict objects to be serialized set the safe parameter to False. i sending message data in list array.. 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())
    receiver = 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):
        data = JSONParser().parse(request) #type list
        serializer = MesSerializer(data= data, many = True) #type list
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)

and when i open message api: enter image description here



Solution 1:[1]

You don't need to parse request before serializing. Just pass request.data as serializer argument:

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)

UPD

receiver is CharField, so you cannot use SlugRelatedField for it. Just use default CharField for it in serializer also:

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

Solution 2:[2]

When we return data as JsonResponse(...) from your view, Django's JsonResponse() expects your JSON data to be in key:value pairs. For example:

class Login(APIView):
     def get(self,request):
     ................
     token = 'abcd'
     return JsonResponse(token)

but here the variable token is not a dictionary with key:value pair, thus JsonResponse has to be told "hey this isn't the regular key value but it's not a mistake, I intentionally want to send a single value as json."

So to tell that to JsonResponse we need to pass set safe=False:

class Login(APIView):
     def get(self,request):
     ................
     token = 'abcd'
     return JsonResponse(token, safe=False)

If you don't want to specify that in your return statement, you can use the ordinary Response().

class Login(APIView):
 def get(self,request):
 ................
 token = 'abcd'
 return Response(token)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 richardec