serializer.is_valid returns false with an error that the field is required even though I am passing it

Viewed 684

I am building a serializer so that if I post using the following command curl -d '{"food": "test", "portion": 12}' http://127.0.0.1:8000/food it will save to the db. However my problem is serializer.is_valid() returns false with an error that the field "food" is required even though I am passing it. I am unable to change the curl command so how can I make it work? Any help is appreciated.

views.py

class FoodAPIView(APIView):
    def post(self, request):
        try:
            data = json.loads(request.body)
        except:
            return Response({"message": "ERROR DETECT"})
        serializer = FoodSerializer(data=request.data)
        if serializer.is_valid():
            //save 
        else:
            print(serializer.errors)//{'food': [ErrorDetail(string='This field is required.', code='required')]}
            return Response({'message': 'ERROR DETECT'}) 

serializer.py

class FoodSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ["food", "portion"]

Output

FoodSerializer(data=<QueryDict: {'{"food": "test", "portion": 12}': ['']}>):
    food = CharField(max_length=8)
    portion = IntegerField(required=False)
1 Answers

If you work with a JSON blob, you need to process data, not request.data since request.data works as if you pass the data with a www-form-urlencode:

class FoodAPIView(APIView):
    def post(self, request):
        try:
            data = json.loads(request.body)
        except:
            return Response({"message": "ERROR DETECT"})
        #      use data, not request.data ↓
        serializer = FoodSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
        else:
            print(serializer.errors)
            return Response({'message': 'ERROR DETECT'})

You furthermore should make a POST request and use application/json as content type, and thus test this with:

#        ↓ POST request            ↓ JSON content type
curl -X POST -H 'Content-Type: application/json' -d '{"food": "test", "portion": 12}' http://127.0.0.1:8000/food
Related