Parsing / Deserializing a JSON String

1,275 views
Skip to first unread message

Eric

unread,
Sep 2, 2009, 1:37:40 PM9/2/09
to Django users
Hi,
I am attempting to parse a json string passed to my view via a form
post. A simple example of my json structure is as follows (indented
for readability):

{
"ganttgroups":[
{
"gantts":[
{
"rows":[
{"stt":1, "end":2, "ttl":"test row - gr1 ga1
ta1", "own":"Tim Johnson"},
{"stt":2, "end":3, "ttl":"my row (g1 t2)",
"own":"John Doe"},
{"stt":1, "end":2, "ttl":"test row - gr1 ga1
ta3", "own":"Mary Smith"}
]
},
{
"rows":[
{"stt":1, "end":2, "ttl":"My 4th task",
"own":"Eric Johnson"},
{"stt":1, "end":2, "ttl":"my row (g2 t2)",
"own":"Jeff Smith"},
{"stt":1, "end":2, "ttl":"test row - gr1 ga2
t3", "own":"Bill Baker"}
]
}
],
"start":"2009-1-01"
}
,{
"gantts":[
{
"rows":[
{"stt":1, "end":2, "ttl":"row - gr2 ga1 t1",
"own":"Ted Tillman"},
{"stt":1, "end":2, "ttl":"row - gr2 ga1 t2",
"own":"Kim Crane"},
{"stt":1, "end":2, "ttl":"row - gr2 ga1 t3",
"own":"Bob Barker"}
]
}
],
"start":"2009-1-01"
}
]
}

I would like to parse it so that I can loop over the pairs/arrays to
access the data. When I try to deserialize the data, I get the django
error "string indices must be integers". Can anybody please help me
determine what exactly this means and how I may fix this? Is there
another method I should be using? I am obviously a bit of a newbie at
this so any help would be greatly appreciated.

Eric

unread,
Sep 2, 2009, 1:40:08 PM9/2/09
to Django users
I forgot to mention that I am trying to deserialize the data as
follows:

"
...
gantt_data = request.POST.get('ganttdata')

for obj in serializers.deserialize("json", gantt_data):
<loop logic here>
...

Andrew McGregor

unread,
Sep 2, 2009, 1:41:01 PM9/2/09
to django...@googlegroups.com
> I would like to parse it so that I can loop over the pairs/arrays to
> access the data. When I try to deserialize the data, I get the django
> error "string indices must be integers". Can anybody please help me
> determine what exactly this means and how I may fix this?  Is there
> another method I should be using? I am obviously a bit of a newbie at
> this so any help would be greatly appreciated.

Are you manually deserialising the data?

http://pypi.python.org/pypi/simplejson/

--
Andrew McGregor
07940 22 33 11

Eric

unread,
Sep 2, 2009, 1:47:53 PM9/2/09
to Django users
Im using the Django deserialization method shown here:

http://docs.djangoproject.com/en/dev/topics/serialization/

It goes something like:

"
...
gantt_data = request.POST.get('ganttdata')

for obj in serializers.deserialize("json", gantt_data):
<loop logic here>
...
"


Javier Guerra

unread,
Sep 2, 2009, 2:04:30 PM9/2/09
to django...@googlegroups.com
On Wed, Sep 2, 2009 at 12:37 PM, Eric<elez...@gmail.com> wrote:
>When I try to deserialize the data, I get the django
> error "string indices must be integers"

it's not on your example, but i guess you're missing a colon between a
fieldname and an array, something like this:

....{"gantts"[{"rows".....

instead of

....{"gantts":[{"rows".....

--
Javier

Andrew McGregor

unread,
Sep 2, 2009, 2:30:53 PM9/2/09
to django...@googlegroups.com
On Wed, Sep 2, 2009 at 6:47 PM, Eric<elez...@gmail.com> wrote:
>
> Im using the Django deserialization method shown here:
>
> http://docs.djangoproject.com/en/dev/topics/serialization/
>

ok, try pasting your json (the original, not your re-typed version) here:

http://www.jsonlint.com/

Eric

unread,
Sep 3, 2009, 12:59:23 PM9/3/09
to Django users
Here is a raw example of the json.. Note that it is a different
example than above:

{"ganttgroups":[{"gantts":[{"rows":[{"stt":1,"end":2,"ttl":"wash
dog","own":"Joe"},{"stt":2,"end":3,"ttl":"clean house"},{"stt":3,"end":
5,"ttl":"sell couch","own":"Mary"}]},{"rows":[{"stt":1,"end":
5,"ttl":"eat diner"},{"stt":5,"end":7,"ttl":"frame","own":"Ed"},{"stt":
6,"end":10,"ttl":"the rest","own":"Chris"}]}],"start":"2009-1-01"},
{"gantts":[{"rows":[{"stt":3,"end":5,"ttl":"1st try","own":"Bill"},
{"stt":5,"end":9,"ttl":"2nd try","own":"Jeff"},{"stt":9,"end":
12,"ttl":"3rd try"}]}],"start":"2009-1-01"}]}

On Sep 2, 11:30 am, Andrew McGregor <a...@txm.net> wrote:

J. Cliff Dyer

unread,
Sep 3, 2009, 4:09:03 PM9/3/09
to django...@googlegroups.com
I suspect your error is hiding in <loop logic here>. What do you expect
obj to be? Your JSON should return a big dictionary with one key
("ganttgroups"). When you iterate over a dictionary in python, you get
the keys of that dictionary. In this case, the string "ganttgroups".
You may be doing the following:

for obj in serializers.deserialize("json", gantt_data):
do_something_to(obj['gantts'])

which returns an error, because it evaluates to "ganttgroups"['gantts']
(which would give you the error you see.

What you want is more like:

for obj in serializers.deserialize('json', gantt_data)['ganttgroups']:
start = obj['start']
for gantt in obj['gantts']:
for row in gantt['rows']:
print row['own']

In short, you're getting your dicts and lists mixed up, or your keys and
values.

Cheers,
Cliff

Eric

unread,
Sep 5, 2009, 7:12:54 PM9/5/09
to Django users
Thank you for your input. I tried what you suggested by first just
trying to loop through the data like so:

"
test_output = 0
for obj in serializers.deserialize('json', gantt_data)['ganttgroups']:
test_output = test_output + 1
"

This generated the following error:

"'generator' object is unsubscriptable"

I tried changing it slightly, moving "['ganttgroups']" inside the
brackets, to this:

"
test_test_output = 0
for obj in serializers.deserialize('json', gantt_data['ganttgroups']):
test_output = test_output + 1
"

This generated the error I originally received:

"string indices must be integers"

I am just so new to this that I'm not sure where to go from here. Do
you have any other suggestions as to what I may be doing wrong?
Again, any help with this would be greatly appreciated.

J. Clifford Dyer

unread,
Sep 6, 2009, 6:42:12 PM9/6/09
to django...@googlegroups.com


On Sat, 2009-09-05 at 16:12 -0700, Eric wrote:
> Thank you for your input. I tried what you suggested by first just
> trying to loop through the data like so:
>
> "
> test_output = 0
> for obj in serializers.deserialize('json', gantt_data)['ganttgroups']:
> test_output = test_output + 1
> "
>
> This generated the following error:
>
> "'generator' object is unsubscriptable"
>

Huh. Okay. I didn't realize deserialize would return a generator.

> I tried changing it slightly, moving "['ganttgroups']" inside the
> brackets, to this:
>
> "
> test_test_output = 0
> for obj in serializers.deserialize('json', gantt_data['ganttgroups']):
> test_output = test_output + 1
> "
>
> This generated the error I originally received:
>
> "string indices must be integers"
>

Yes. Now you're trying to subscript gantt_data before you deserialize
it. As you know, gantt_data is a json string. Hence the error.

> I am just so new to this that I'm not sure where to go from here. Do
> you have any other suggestions as to what I may be doing wrong?
> Again, any help with this would be greatly appreciated.
>

Well, the first thing you need to do is figure out what you have to work
with. You know now that deserializer returns a generator, so try
looping over it to see what it yields each time around:

for obj in serializers.deserialize('json', gantt_data):
print '---'
print type(obj)
print obj

That should give you a hint how to proceed. If you need more clues,
then add:

print dir(obj)
print help(obj)

That will give you some hints as to what you can do with obj.

Eric

unread,
Sep 11, 2009, 12:54:39 PM9/11/09
to Django users
As I have been receiving all along, the code you suggested gives me
the following error:

"
TypeError at /course/savegantt/

string indices must be integers
"

There must be something not quite right about the for loop statement
("for obj in serializers.deserialize('json', gantt_data): ")
Reply all
Reply to author
Forward
0 new messages