Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#33219 closed Bug (invalid)

django.test.client missconversion of json with internal dicts

Reported by: Caperutxa Owned by: nobody
Component: Testing framework Version: 3.2
Severity: Normal Keywords: test.client, complex json
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

django.test.client is used to tests post resquest in a django restframework application with json as file content.

For basic json works : {'name': 'Mateu', 'number': 25}

But if the json has internal dictionaries it is transformed to an array:
From {'name': 'Mateu', 'number': 25, sales: {'Hubble':25, 'Web':4, 'telescope': 0}}
To <QueryDict: {'name': 'Mateu', 'number': 25, sales: ['Hubble', 'Web', 'telescope']}
Then it is not possible to iterate over all sales key-value pairs

Also, if in the code a sales list is requested, it give only the last value (in that case telescope)

sales = request.datasales --> sales will be 'telescope' instead of an array at least

NOTE, that starting the real server and run a request via curl or via web browser, it works as expected (a json with internal dictionaries or arrays)


django-cors-headers 3.10.0
django-extensions 3.1.3
django-storages 1.11.1
djangorestframework 3.12.4
pytest-django 4.4.0

linux system (ubuntu)


Sample code (set the urls yourself)

Inside views

    @api_view(['POST']) 
    def store_iteration(request):
        print(request.data)
        print(request.data['sales'])

Inside tests

    class IterationsTestCase(TestCase):
        def setUp(self):
            self.client = Client()

        def test_fake_up(self):
            response = self.client.post('/api/test_it',
                              {'name': 'Mateu', 'number': 25, sales: {'Hubble':25, 'Web':4, 'telescope': 0}},
                              format='json')

Change History (5)

comment:1 by Mariusz Felisiak, 3 years ago

Resolution: invalid
Status: newclosed

Thanks for the report, however I don't see any issue in Django here. format is not an argument of Client.post(), you should use content_type='application/json' instead.

If you're having trouble understanding how Django works, see TicketClosingReasons/UseSupportChannels for ways to get help.

comment:2 by Caperutxa, 3 years ago

It is solved using content_type='application/json'

https://stackoverflow.com/a/14669551/9794948

Please, could you update it in your documentation.

Regards

comment:3 by Mariusz Felisiak, 3 years ago

Please, could you update it in your documentation.

What do you mean? format is not mentioned in Django docs.

comment:4 by Carlton Gibson, 3 years ago

This looks like a confusion with Django REST Framework's APIClient, which does accept the format parameter.
The docs for that a here.

Version 0, edited 3 years ago by Carlton Gibson (next)

comment:5 by Caperutxa, 3 years ago

I mean the parameter content_type='application/json' is not mentioned in the documentation like that

https://docs.djangoproject.com/en/3.2/topics/testing/tools/

There are a lot of uses of the client without any content_type parameter such as

>>> c.post('/login/?visitor=true', {'name': 'fred', 'passwd': 'secret'})
Note: See TracTickets for help on using tickets.
Back to Top