Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

serializing result of a queryset with json raises error:

I was trying to serialize a Python list but got errors that it's not serializable. Is there a limitation on serializing a list of Long integers?

>>> ids=p.values_list('id',flat=True)
>>> ids
[335L, 468L, 481L, 542L, 559L, 567L, 609L]
>>> import simplejson as json
>>> str=json.dumps(ids)

Traceback (most recent call last):
   File "<console>", line 1, in <module>
  File "C:\Program Files\Google\google_appengine\lib\simplejson\simplejson\__ini
t__.py", line 265, in dumps
    return _default_encoder.encode(obj)
  File "C:\Program Files\Google\google_appengine\lib\simplejson\simplejson\encod
er.py", line 216, in encode
    chunks = list(chunks)
  File "C:\Program Files\Google\google_appengine\lib\simplejson\simplejson\encod
er.py", line 495, in _iterencode
    o = _default(o)
  File "C:\Program Files\Google\google_appengine\lib\simplejson\simplejson\encod
er.py", line 190, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: [335L, 468L, 481L, 542L, 559L, 567L, 609L] is not JSON serializable
>>>
like image 362
afshin Avatar asked Jul 16 '11 20:07

afshin


2 Answers

"I am trying to serialize a Python list..."
This is actually not quite the full story.
You are trying to serialize a ValuesListQuerySet.

>>> type(ids)
<class 'django.db.models.query.ValuesListQuerySet'>

You can either
1. convert to a Python list as mentioned in the other great answers, or
2. serialize just the IDs.

Django has a built-in way to serialize a QuerySet.
And you only want the IDs so you may use the fields kwarg.

from django.core import serializers
data = serializers.serialize('json', YourEntity.objects.all(), fields=('id',))
like image 82
mechanical_meat Avatar answered Oct 21 '22 22:10

mechanical_meat


EDIT after reading the other answers

The original answer I gave (here below unabridged) was correct in diagnosing what the problem is (the argument passed to the json function is not a list). I am leaving it as it explains the debugging procedure (maybe of some use for other similar situations), but the new answers of both @Jacinda and @Adam are more "to the point". In particular, the latter contains instructions on how to use a native django functionality to overcome the problem.

Original answer

Not 100% sure because I can't replicate the problem on my system, but from the look of it, it seems to me that it's a problem in the type/encoding of the data.

I would start by testing again your code by manually assign ids with:

ids = [335L, 468L, 481L, 542L, 559L, 567L, 609L]

(on my system your code works in this case). If it works for you too, then investigate what kind of object is ids when assigned via p.values_list('id',flat=True) [you can do that with type(ids)]. It might be that ids is an object whose representation is the same as a list, but that it's not a list.

In this case, you could try typecasting: ids = list(p.values_list('id',flat=True)) before passing it to the json function but there is no guarantee that it will work (it depends if the returned value of p.values_list is iterable or not.

HTH in at least tracking down the issue!

like image 34
mac Avatar answered Oct 21 '22 21:10

mac