Raphael
Raphael

Reputation: 8192

Django Rest Framework does not deserialize data passed as raw JSON

I have the following view:

class Authenticate(generics.CreateAPIView):
    serializer_class = AuthSerializer

    def create(self, request):
        serializer = AuthSerializer(request.POST)
        # Do work here

This works well if the data is passed as a form, however, if the data is passed as a raw JSON the serializer is instantiated with all it's fields set to None. The documentation does mention that there should be anything specific to processing a raw JSON argument.

Any help would be appreciated.

UPDATE

I have the following work around in order to make the Browsable API work as expected when passing a raw JSON but I believe there must be a better way.

def parse_data(request):
    # If this key exists, it means that a raw JSON was passed via the Browsable API
    if '_content' in request.POST:
        stream = StringIO(request.POST['_content'])
        return JSONParser().parse(stream)
    return request.POST


class Authenticate(generics.CreateAPIView):
    serializer_class = AuthSerializer

    def create(self, request):
        serializer = AuthSerializer(parse_data(request))
        # Do work here

Upvotes: 6

Views: 3730

Answers (2)

Tom Christie
Tom Christie

Reputation: 33901

You're accessing the request data the wrong way - request.POST only handles parsing form multipart data.

Use REST framework's request.data instead. That'll handle either form data, or json data, or whatever other parsers you have configured.

Upvotes: 11

Hieu Nguyen
Hieu Nguyen

Reputation: 8623

I guess that's the way it is when you are using Browsable API then.

I think you shouldn't use Browsable API to test JSON request, use curl instead:

curl -v -H "Content-type: application/json" -X POST -d '{"foo": 1, "bar": 1}' http://127.0.0.1:8000/api/something/

Hope it helps.

Upvotes: 1

Related Questions