views:

622

answers:

4

I've been searching around trying to find an answer to this question, and I can't seem to track it down. Maybe it's too late in the evening to figure the answer out, so I turn to the excellent readers here.

I have the following bit of JSON data that I am pulling out of a CouchDB record:

"{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"},"

This data is stored inside a Python dict under the key 'locations' in a dict called 'my_plan'. I want to covert this data from CouchDB into a Python dict so I can do the following in a Django template:

{% for location in my_plan.locations %}                                                           
<tr>
    <td>{{ location.place }}</td>
    <td>{{ location.locationDate }}</td>
</tr>

{% endfor %}

I've found lots of info on converting dicts to JSON, but nothing on going back the other way

Thanks in advance for the help!

A: 
django.utils.simplejson.loads(someJson)
Ignacio Vazquez-Abrams
Doesn't convert to a dict. I did try that ;)
GrumpyCanuck
The actual error it gives is "Extra data: line 1 column 151 - line 1 column 304 (char 151 - 304)"
GrumpyCanuck
Then you don't have JSON.
Ignacio Vazquez-Abrams
@GrumpyCanuck, Look closely. This isn't one object. It's an object then a comma then an object then a comma.
Mike Graham
Yeah, I figured that out when I saw @Alex Martelli's answer
GrumpyCanuck
+2  A: 

The string you show is not a JSON-coded object (eqv to a Python dict) -- more like an array (eqv to a list) without brackets and with a stray extra comma at the end. So (using simplejson for version portability -- the stndard library's json in 2.6 is fine too of course!-):

>>> import simplejson                                                           >>> js = "{\"description\":\"fdsafsa\",\"order\":\"1\",\"place\":\"22 Plainsman Rd, Mississauga, ON, Canada\",\"lat\":43.5969175,\"lng\":-79.7248744,\"locationDate\":\"03/24/2010\"},{\"description\":\"sadfdsa\",\"order\":\"2\",\"place\":\"50 Dawnridge Trail, Brampton, ON, Canada\",\"lat\":43.7304774,\"lng\":-79.8055435,\"locationDate\":\"03/26/2010\"},"
>>> simplejson.loads('[%s]' % js[:-1])

[{'description': 'fdsafsa', 'order': '1', 'place': '22 Plainsman Rd, Mississauga, ON, Canada', 'lat': 43.596917500000004, 'lng': -79.724874400000004, 'locationDate': '03/24/2010'}, {'description': 'sadfdsa', 'order': '2', 'place': '50 Dawnridge Trail, Brampton, ON, Canada', 'lat': 43.730477399999998, 'lng': -79.805543499999999, 'locationDate': '03/26/2010'}]

If you really want a dict you'll have to specify how to treat these two unnamed items, i.e., what arbitrary keys you want to slap on them...?

Alex Martelli
Your solution worked perfectly. Thanks! I will fix the routine that *generates* that data before it goes into CouchDB to not append that extra comma. A bit of late-night coding sloppiness
GrumpyCanuck
@Grumpy, sure -- if I were you, I'd also put the brackets around the string in the DB, just to make sure it's valid JSON rather than "somewhat incomplete JSON" that the receiving code must complete.
Alex Martelli
I was doing that before, but cannot remember why I *stopped* doing it...late-night coding requires notes from now on I think
GrumpyCanuck
A: 
  • Use the json module for loading JSON. (Pre-2.6 use the third party simplejson module, which has the same exact API.)

    >>> import json
    >>> s = '{"foo": 6, "bar": [1, 2, 3]}'
    >>> d = json.loads(s)
    >>> print d
    {u'foo': 6, u'bar': [1, 2, 3]}
    
  • Your actual data cannot be loaded this way since it's actually two JSON objects separated by a comma and with a trailing comma. You'll need to separate them or otherwise deal with this.

    • Where did you get this string?
Mike Graham
That string is from data being generated by an application I am working on, sort of a location-and-date social app for people planning trips, pub crawls, etc
GrumpyCanuck
A: 

This is not an answer to your question, but I've had enough grief with it that I'll point it out.

Be very careful with Unicode and JSON. All strings in JSON are in Unicode, and UTF-8 by default. Also, JSON's idea of Unicode and quoting might not be quite what you expect. Do extra testing, for the errors are subtle and fatal.

Charles Merriam