[Django]-DRF testing: instead of JSON an OrderedDict is returned

13👍

As explained here, this is because the default format for requests during tests is multipart instead of json. You can specify the format by providing it to your api call like so:

response = self.client.get('/something/1', format='json')

Or you can set the default test request format in your settings.py like so:

REST_FRAMEWORK = {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',  # Use application/json instead of multipart/form-data requests in tests.
}

To fix it for all your tests automagically.

10👍

It sounds like you’re using response.data (which returns the parsed json objects) instead of response.content (which gives the raw json string).

See http://www.django-rest-framework.org/api-guide/testing/#testing-responses

👤Norgg

5👍

If your tests look something like this:

class SomeTests(APITestCase):
    def test_something(self):
        response = self.client.get('/something/1')
        # assertions with response

Then response will certainly be an OrderedDict rather than a JSON document. Luckily Django 1.9 has introduced the response.json() method (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#django.test.Response.json) so you can easily convert the response into JSON. Note that you could also use python’s json library.

The catch here is that Django’s test client (that DRF extends) is a “dummy browser” (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#the-test-client) and doesn’t work exactly like an in-browser framework such as Selenium would. Thus, HTTP calls are actually just simulated HTTP calls that focus on testing your logic and that correct routing/views/serializers/etc. are being used.

3👍

You can dump your data into json format :

import json
return HttpResponse(json.dumps(data))

2👍

I solved the problem by using SerializerMethodField.

Simply, within the serializer class copy next last 3 lines and replace result with the json member that cause the problem

class ConfigSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Config
        fields = ('id', 'url', 'email', "result",)

    # COPY NEXT 3 LINES AND CHANGE 'result' WITH THE JSON MEMBER THAT CAUSE THE PROBLEM
    result = serializers.SerializerMethodField()
    def get_result(self, obj):
        return obj.result

Before the result shows as:

{result: "OrderedDict([('key1', 1), ('key2', OrderedDict([('key3', [1, 2, 3])]))])"}

After solution, result become:

{"result": {"key1":1,"key2":{"key3":[1,2,3]}}}

Leave a comment