3

When I send a POST message to the GAE with a json parameters using POST the QueryDict parsed by the server is not parsed like a json ...

I found a similar problem in this issue: iphone Json POST request to Django server creates QueryDict within QueryDict

Maybe is a problem with the GAE configuration. I've Python 2.6.6 with the last version of GAE. First of all, If I get the POST with a nc tool, the POST message is perfect:

POST /url/ HTTP/1.1
Accept: application/jsonrequest
Content-type: application/json
Accept-Encoding: gzip
Content-Length: 458
Host: 192.168.1.1:8080
Connection: Keep-Alive

{"id":"xxx","jsonrpc":"2.0","method":"XXX","params":{...}]}

And in the server console I receive the next messages:

DEBUG    2010-09-16 06:47:05,891 dev_appserver.py:1693] Access to module file denied: /usr/lib/pymodules/python2.6/simplejson
DEBUG    2010-09-16 06:47:05,894 dev_appserver.py:1700] Could not import "_json": Disallowed C-extension or built-in module
DEBUG    2010-09-16 06:47:05,897 dev_appserver.py:1700] Could not import "_json": Disallowed C-extension or built-in module

And idea ¿?

The query dict in the server is <QueryDict: {u'{"id":"xxx","jsonrpc":"2.0","method":"XXX","params":{...}}': [u'']}>

As you can check the django handler parse the json of the POST request as a key of a new dictionary ...

In the linked issue there's the next solution ...

hack_json_value = request.POST.keys()[0]
hack_query_dict = json.loads(hack_json_value)
foo = hack_query_dict['foo']
bar = hack_query_dict['bar']

but maybe you can help me to find another one ...

Thanks,

Community
  • 1
  • 1
Iván Peralta
  • 851
  • 1
  • 9
  • 25

3 Answers3

7

The first thing you need to remember when working with json is that AppEngine lives with python 2.5. This means json is not a standard part of python yet.

To solve that bit I found simplejson somewhere online and packed it together with my code. The API for built-in json and simplejson are essentially the same (or maybe I've just not noticed anything different) so just import it like so:

import simplejson as json

And use it like you're used to.

Now, as for the QueryDict. Yes, what you're getting through is raw POST data, there is no logical reason for it to get parsed as json and play pretend that it's a normal query-based POST request. Honestly, I never thought django was even able of making this leap of judgement for us. So, to get to your data use something along these lines:

data = json.loads(request.raw_post_data)

For reference of what django was expecting to see in the raw POST data check here: http://en.wikipedia.org/wiki/POST_(HTTP), specifically the bit about how application/x-www-form-urlencoded works.

kbec
  • 3,415
  • 3
  • 27
  • 42
Swizec Teller
  • 2,322
  • 1
  • 19
  • 24
  • 2
    Actually you don't have to upload simplejson with your code. It's accessible directly on App Engine via : from django.utils import simplejson – Franck Sep 16 '10 at 14:07
  • There is also an answer to another question providing the same solution : http://stackoverflow.com/questions/1208067/wheres-my-json-data-in-my-incoming-django-request/3244765#3244765 – Franck Sep 16 '10 at 14:10
  • Yes sorry I'm already using simplejson. Btw this method simplejson.loads(request.raw_post_data) works perfectly. Thanks!!! – Iván Peralta Sep 16 '10 at 14:11
  • Really? Thanks Franck, had no idea it was already available :) – Swizec Teller Sep 16 '10 at 14:17
  • import simplejson and use data = simplejson.loads(request.body) instead request.raw_post_data – Antaresm Dec 30 '13 at 14:21
1

request.raw_post_data is deprecated in Django 1.4.3 and removed in 1.5

https://github.com/django/django/commit/4a6490a4a0d0d7e45b1f549e3f9d97e5e2aeb731

attomos
  • 1,112
  • 3
  • 16
  • 30
1
import simplejson

and use

data = simplejson.loads(request.body)

instead request.raw_post_data

Antaresm
  • 580
  • 2
  • 5
  • 19