Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 520
Raphael Avatar asked Jul 24 '13 19:07

Raphael


People also ask

What is the purpose of serialization in Django REST framework?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

What is JSONParser Django?

JSONParser. Parses JSON request content. request. data will be populated with a dictionary of data.

Is Django REST framework fast?

Django/Python/REST framework is too slow. As this article will argue, the biggest performance gains for Web APIs can be made not by code tweaking, but by proper caching of database lookups, well designed HTTP caching, and running behind a shared server-side cache if possible.


2 Answers

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.

like image 112
Tom Christie Avatar answered Sep 29 '22 07:09

Tom Christie


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.

like image 30
Hieu Nguyen Avatar answered Sep 29 '22 07:09

Hieu Nguyen