1

I have a very simple use case of data that I wish to serialize to JSON, but I keep getting tripped by error TypeError: <api.tests.MemberInfo object at 0x02B26210> is not JSON serializable

Here is the object I want to serialize -

class MemberInfo:
    def __init__(self, member_code):
        self.memberCode = member_code

In Python shell -

>>> mi = MemberInfo('123')
>>> json.JSONEncoder().default(mi)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "c:\Python34\lib\json\encoder.py", line 173, in default
    raise TypeError(repr(o) + " is not JSON serializable")

How can I find out the cause?

self.
  • 1,612
  • 4
  • 18
  • 35
  • 2
    the json module from the Python Standard Library and Django models don't get along very well. I've grown accustomed to using jsonpickle instead: http://jsonpickle.github.io/ – Brandon Taylor Oct 03 '14 at 18:56
  • Can you please add your model fields? It will help determine which of them isn't serializable. – Brandon Taylor Oct 03 '14 at 19:45

3 Answers3

1

You could embed in your class a property to return data as JSON.

from json import dumps

class MemberInfo:

    def __init__(self, member_code, member_name):
        self.memberCode = member_code
        self.memberName = member_name

    @property
    def json(self):
        return dumps({'code': self.memberCode, 'name': self.memberName})

member = MemberInfo(1234, 'Johnny Cash')
member.json
'{"code": 1234, "name": "Johnny Cash"}'
Mauro Baraldi
  • 6,346
  • 2
  • 32
  • 43
1

The cause is simply that you haven't told it how to.

JSON is a fairly restrictive format, and can pretty much only cope with strings, integers, lists and dicts. Not even datetimes can be serialised directly. So if you want to serialise a Django model, you need to provide some form of representation in terms of the toes that json does understand.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
1

The problem is that the json serializer does not know how to serialize classes and that's why it stops working.

If you convert your class to a dictionary with all the properties and its values using only primitive types you can serialize it without any problems. Here is an example of how it works:

import json
from decimal import Decimal

class MemberInfo:
    def __init__(self, member_code):
        self.memberCode = member_code

    def to_dict(self):
        return dict(memberCode=self.memberCode)

instance = MemberInfo('123123')

try:
    # This will break since classes cannot be serialized
    json.dumps(instance)
except TypeError as e:
    print 'CLASS ERROR: %s' % e.message

# This will also break since it has a class Decimal
instance = dict(memberCode=Decimal(123123))
try:
    # This will break since classes cannot be serialized
    json.dumps(instance)
except TypeError as e:
    print 'CLASS ERROR: %s' % e.message


# This will work since there aren't any classes and all keys are simple types
instance = MemberInfo('123123').to_dict()

print 'This will return a valid result'
print json.dumps(instance)
Alex Carlos
  • 882
  • 5
  • 7