How do I read a JSON object in Python?
May 17, 2010 10:55 AM   Subscribe

I'm mostly a front end guy, but I have worked with Django and Python before, so I thought it would be perfect for a web app idea I had. I actually understand it pretty well (or maybe not!), but I'm having an issue with an Ajax call I am trying to make.

I'm passing a JSON object back to Python with jQuery and it seems to accept it in the correct format, but I have no idea how to actually access and iterate through the object in Python. If I simplify the code down to

a = request.POST
return HttpResponse(a)

and console.log it to Firebug, it looks like a valid JSON object. I also tried passing it through as plain text, with equaly frustrating results. Every time I try to access it in Python I get an error about the QueryDict or unicode not having the attribute I'm trying to access. Googling has turned up something about serializing/deserializing, but I don't know the correct syntax to handle a JSON object made up of other objects like this:
[{name:"name", message:"text"}, {name:"name", message:"text"}, {name:"name", message:"text"}]

How do I iterate through the object and get at the data so I can save it to the database?
posted by lovetragedy to Computers & Internet (7 answers total) 1 user marked this as a favorite
 
You need to use simplejson module to decode json format to python format. I think python now has built-in module to do that but depending on your python version it may not be available. simplejson will definitely work I used it in a few projects.
posted by rainy at 11:05 AM on May 17, 2010


Best answer: Are you using Python's JSON package or simplejson? Without one of them, Python doesn't know anything about the JSON coming in, as it's just plain text.
import json # if using Python's built in JSON package, otherwise "import simplejson as json"

# Parse the JSON
objs = json.loads(request.POST)

# Iterate through the stuff in the list
for o in objs:
    # Do something Djangoey with o's name and message, like
    record = SomeDjangoModel(name = o.name, message = o.message)
    record.save()

posted by zsazsa at 11:10 AM on May 17, 2010


It'd be easier to get an idea of what you were trying to do if you could show us the actual code that isn't working the way you'd like.

I take it from the mention of QueryDict that you're using Django. There's a copy of simplejson built in if you're using a version of python < 2.6
posted by SemiSophos at 11:14 AM on May 17, 2010


I see Django uses a QueryDict for HTTP GET and POST parameters. If you're passing the JSON data as a POST operation, you will need to use QueryDict.getlist(), otherwise you'll just get the first member of that list. This is because you can specify multiple parameters in a GET or POST request with the same value, and Django/Pylons/WSGI will default to the first or last parameter with the same name. You may be confusing it by sending it a list. See the thread at: http://www.mail-archive.com/django-users@googlegroups.com/msg50868.html.

I actually think that should fix it. If it doesn't, can you iterate through the QueryDict to see what you're getting? Try something like:
for key, value in request.iteritems():
    print key, value # or send it out to your logging system
Also, for your reference, here's how to de-serialize a JSON string. First, you need to determine the type of object you're getting. If it's a unicode object, de-serialization is really simple. Import json, take the unicode object and pass it through json.loads(), and you'll get Python objects in return. For example:


>>> import json
>>> d = [{'foo': 'bar'}, {'fubar': 'snafu'}]
>>> json.dumps(d)
'[{"foo": "bar"}, {"fubar": "snafu"}]' #note string type
>>> json.loads('[{"foo": "bar"}, {"fubar": "snafu"}]')
[{u'foo': u'bar'}, {u'fubar': u'snafu'}] # note list of dictionaries.

posted by ayerarcturus at 11:18 AM on May 17, 2010


Response by poster: zsazsa and ayerarcturus: those look to be what I'm looking for. I was flirting with similar syntax but couldn't get it quite right. I'm going to give those a shot when I get home. Thank you both for providing examples, as I couldn't find any code examples for what I was doing.

SemiSophos: I actually don't have access to the code right now, as it's something I'm working on at home, but I am indeed working with Django and that code I posted is not far off. I simplified the AJAX view down to simply returning what it was receiving.

To answer everyone, I do have access to simplejson, so I can use that.
posted by lovetragedy at 11:23 AM on May 17, 2010


Best answer: Oh, my above example won't work. You can't deserialize Django's request.POST object directly. If jQuery is sending you the JSON object totally raw in the POST:
objs = json.loads(request.raw_post_data)

Otherwise it'll be sending it inside a named POST variable, named 'jsonData' or something similar:
objs = json.loads(request.POST['jsonData'])
posted by zsazsa at 11:34 AM on May 17, 2010


Response by poster: THANK YOU ZSAZSA!

Also, ayerarcturus, your answer was extremely useful in explaining JSON decoding.
posted by lovetragedy at 8:07 PM on May 17, 2010


« Older Pump us up   |   How do I make this thing? (video-editing mystery) Newer »
This thread is closed to new comments.