在使用时
from django.utils import simplejson
对于从db.Model
派生的类型的对象,它会抛出异常。如何规避这一点?
发布于 2010-01-24 03:26:19
由于找不到合适的解决方案,我编写了自己的解决方案,它不完全是JSON序列化程序,而是Javascript序列化程序
from google.appengine.ext import db
from google.appengine.api.datastore_types import *
def dumpStr(obj):
return "'" + obj + "'"
def dumps(obj):
if isinstance(obj, str):
return dumpStr(obj)
elif obj == None:
return None
elif isinstance(obj, list):
items = [];
for item in obj:
items.append(dumps(item))
return '[' + ','.join(items) + ']'
elif isinstance(obj, datetime.datetime):
return "new Date('%s')" % obj.ctime()
properties = [];
for property in dir(obj):
if property[0] != '_':
value = obj.__getattribute__(property)
valueClass = str(value.__class__)
if not(('function' in valueClass) or ('built' in valueClass) or ('method' in valueClass)):
value = dumps(value)
if value != None:
properties.append("'" + property + "':" + value)
if len(properties) == 0:
return str(obj)
else:
return '{' + ','.join(properties) + '}'
发布于 2010-02-25 18:07:40
Jader Dias提供的示例在经过一些调整后可以很好地满足我的关注。移除encode方法,因为它包含循环引用。调整后的类应该如下所示:
import datetime
import time
from google.appengine.api import users
from google.appengine.ext import db
from django.utils import simplejson
class GqlEncoder(simplejson.JSONEncoder):
"""Extends JSONEncoder to add support for GQL results and properties.
Adds support to simplejson JSONEncoders for GQL results and properties by
overriding JSONEncoder's default method.
"""
# TODO Improve coverage for all of App Engine's Property types.
def default(self, obj):
"""Tests the input object, obj, to encode as JSON."""
if hasattr(obj, '__json__'):
return getattr(obj, '__json__')()
if isinstance(obj, db.GqlQuery):
return list(obj)
elif isinstance(obj, db.Model):
properties = obj.properties().items()
output = {}
for field, value in properties:
output[field] = getattr(obj, field)
return output
elif isinstance(obj, datetime.datetime):
output = {}
fields = ['day', 'hour', 'microsecond', 'minute', 'month', 'second', 'year']
methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 'timetuple']
for field in fields:
output[field] = getattr(obj, field)
for method in methods:
output[method] = getattr(obj, method)()
output['epoch'] = time.mktime(obj.timetuple())
return output
elif isinstance(obj, datetime.date):
output = {}
fields = ['year', 'month', 'day']
methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 'timetuple']
for field in fields:
output[field] = getattr(obj, field)
for method in methods:
output[method] = getattr(obj, method)()
output['epoch'] = time.mktime(obj.timetuple())
return output
elif isinstance(obj, time.struct_time):
return list(obj)
elif isinstance(obj, users.User):
output = {}
methods = ['nickname', 'email', 'auth_domain']
for method in methods:
output[method] = getattr(obj, method)()
return output
return simplejson.JSONEncoder.default(self, obj)
因为我已经将这个类保存在一个名为utils.py
的文件中,并在适当的时候使用
import utils
然后我调用utils.GqlEncoder().encode(results)
,例如:
query = User.all()
results = query.fetch(10)
self.response.headers['Content-Type'] = "text/plain" # Alt. application/json
self.response.out.write( utils.GqlEncoder().encode(results) )
结果应该如下所示(我添加了一些换行符,以使其更容易阅读):
[
{"date": {"ctime": "Tue Feb 23 10:41:21 2010", "hour": 10, "isoweekday": 2, "month": 2,
"second": 21, "microsecond": 495535, "isocalendar": [2010, 8, 2], "timetuple": [2010, 2, 23, 10, 41, 21, 1, 54, -1],
"year": 2010, "epoch": 1266921681.0, "isoformat": "2010-02-23T10:41:21.495535", "day": 23, "minute": 41},
"claimed_id": "https:\/\/www.google.com\/accounts\/o8\/id?id=abcdefghijklmnopqrstuvxyz",
"display_name": "Alfred E Neumann",
"email": null,
"full_name": "Alfred E Neumann"
},
{"date": {"ctime": "Tue Feb 23 11:00:54 2010", "hour": 11, "isoweekday": 2, "month": 2,
"second": 54, "microsecond": 805261, "isocalendar": [2010, 8, 2], "timetuple": [2010, 2, 23, 11, 0, 54, 1, 54, -1],
"year": 2010, "epoch": 1266922854.0, "isoformat": "2010-02-23T11:00:54.805261", "day": 23, "minute": 0},
"claimed_id": "http:\/\/openid.domain.net\/john",
"display_name": "",
"email": "jd@domain.net",
"full_name": "John Doe"
}
]
发布于 2010-01-22 12:07:08
除了基本类型之外,json不能用于序列化任何类型,如dict、list、int/long和string(这并不全面)。例如,即使这些简单的命令也不起作用:
import json
json.dumps(object())
如果您想序列化django对象,您应该参考django documentation on serialization,它将使用自己的库,但它们确实支持json。
https://stackoverflow.com/questions/2114659
复制相似问题