Reputation: 1241
I am sending the post request to OrganisationApiView class. The request body contains the following JSON.
{
"organisation_id" : "1",
"organisation_name" "Some Name"
}
views.py
from typing import Optional, Any
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.parsers import JSONParser
from . import serializers
class OrganisationApiView(APIView):
serializers_class = serializers.OrganisationSerializer
parser_classes = [JSONParser]
def get(self, request, formate=None):
return Response({"message": "You are Cool!!"})
def post(self, request, formate=None):
serializer = self.serializers_class(data=request.data)
print(serializer)
if serializer.is_valid():
organisation_name = serializer.validated_data.get('organisation_name')
message = f"Reached POST {organisation_name}"
return Response({'message': message, status: 'HTTP_200_OK'})
else:
return Response(
serializer.errors,
status=status.HTTP_400_BAD_REQUEST
)
def put(self, request, pk=None):
return Response({"message": "PUT"})
def patch(self, request, pk=None):
return Response({"message": "PATCH"})
def delete(self, request, pk=None):
return Response({"message": "Delete"})
I get the response on postman as -
TypeError at /api/organisation/
keys must be str, int, float, bool or None, not module
Request Method: POST
Request URL: http://127.0.0.1:8000/api/organisation/
Django Version: 2.1.15
Exception Type: TypeError
Exception Value:
keys must be str, int, float, bool or None, not module
Exception Location: /usr/local/lib/python3.7/json/encoder.py in iterencode, line 257
Python Executable: /usr/local/bin/python
Python Version: 3.7.6
Python Path:
['/app',
'/usr/local/lib/python37.zip',
'/usr/local/lib/python3.7',
'/usr/local/lib/python3.7/lib-dynload',
'/usr/local/lib/python3.7/site-packages']
Server time: Sat, 4 Jan 2020 06:42:54 +0000
Other requests like GET, PUT, PATCH, DELETE are working just fine. I don't understand what exactly has caused this problem. I have also defined the SimpleSerializers as stated below.
from rest_framework import serializers
class OrganisationSerializer(serializers.Serializer):
organisation_id = serializers.IntegerField()
organisation_name = serializers.CharField(max_length=255, allow_null=False, allow_blank=False)
Also, I don't want to accept the organisation_id as in the models I have defined it as Primary Key. But when I send the JSON without organisation_id it raises an error stating field organisation_id is required. As of now I just want to accept the organisation_name and return it in response.
Upvotes: 1
Views: 1938
Reputation: 917
You are trying to return serializer.errors
as JSON data, but it is not a dictionary, it is a module. You can use serializer.error_messages
instead.
Try this:
else:
return Response(
serializer.error_messages,
status=status.HTTP_400_BAD_REQUEST
)
Better Solution
Since you are only trying to return the details of the serializing process, When calling serializer's is_valid function, you can pass a parameter to trigger an exception if the serializer is not valid. serializer.is_valid(raise_exception=True)
. Its default format will satisfy your needs. The code will be:
def post(self, request, formate=None):
serializer = self.serializers_class(data=request.data)
serializer.is_valid(raise_exception=True)
organisation_name = serializer.validated_data.get('organisation_name')
message = f"Reached POST {organisation_name}"
return Response({'message': message, status: 'HTTP_200_OK'})
Upvotes: 1