11

I'm having a problem very similar to Django's Querydict bizarre behavior: bunches POST dictionary into a single key and Unit testing Django JSON View. However, none of the questions/responses in these threads really point at the specify problem I'm having. I'm trying to use Django's test client to send a request with a nested JSON object (what I have works well with JSON objects with non-JSON values).

Attempt #1: Here's my initial code:

    response = c.post('/verifyNewMobileUser/', 
        {'phoneNumber': user.get_profile().phone_number,
         'pinNumber': user.get_profile().pin,
         'deviceInfo': {'deviceID': '68753A44-4D6F-1226-9C60-0050E4C00067', 'deviceType': 'I'}})

As you can see, I have a nested JSON object within my request data. However, this is what request.POST looks like:

<QueryDict: {u'phoneNumber': [u'+15551234567'], u'pinNumber': [u'4171'], u'deviceInfo': [u'deviceType', u'deviceID']}>

Attempt #2: Then I tried, adding on the content-type parameter as follows:

response = c.post('/verifyNewMobileUser/', 
    {'phoneNumber': user.get_profile().phone_number,
     'pinNumber': user.get_profile().pin,
     'deviceInfo': {'deviceID': '68753A44-4D6F-1226-9C60-0050E4C00067', 'deviceType': 'I'}},
    'application/json')

And what I get now for request.POST is

<QueryDict: {u"{'deviceInfo': {'deviceType': 'I', 'deviceID': '68753A44-4D6F-1226-9C60-0050E4C00067'}, 'pinNumber': 5541, 'phoneNumber': u' 15551234567'}": [u'']}>

All I want to do is be able to specify a nested dict for my request data. Is there an easy way to do this?

Community
  • 1
  • 1
fangsterr
  • 3,670
  • 4
  • 37
  • 54

3 Answers3

24

The following works for me (using named args):

geojson = {
        "type": "Point",
        "coordinates": [1, 2]
    }

    response = self.client.post('/validate', data=json.dumps(geojson),
                                content_type='application/json')
Jason
  • 2,259
  • 2
  • 17
  • 12
6

Your problem indicates Django is interpreting your request as multipart/form-data rather than application/json. Try

c.post("URL", "{JSON_CONTENT}", content_type="application/json").

Another thing to watch is that Python represents dictionary keys/values using single quotes when rendered as strings, which the simplejson parser doesn't like. Keep your hard-coded JSON objects as single-quoted strings, using double quotes inside to get around this...

n3utrino
  • 2,361
  • 3
  • 22
  • 32
Steve Bradshaw
  • 827
  • 7
  • 10
0

My solution is the following:

In the test method:

data_dict = {'phoneNumber': user.get_profile().phone_number,
             'pinNumber': user.get_profile().pin,
             'deviceInfo':
                 {'deviceID': '68753A44-4D6F-1226-9C60-0050E4C00067',
                  'deviceType': 'I'}})

self.client.post('/url/', data={'data': json.dumps(data_dict)})

In the view:

json.loads(request.POST['data'])

This sends post['data'] as a string. The in the view one must load the json from that string.

Thanks.

luistm
  • 1,027
  • 4
  • 18
  • 43