`
阿尔萨斯
  • 浏览: 4195930 次
社区版块
存档分类
最新评论

Appengine中的JSON序列化

 
阅读更多

Simplejson是不能直接把Appengine中的db.Model序列化成JSON的,我是这么做的:
Model模块做如下扩展:


def getter(func):
if not func.__name__.startswith("get_"):
raise InvalidMethodName("method name must start with 'get_'")
func.getter = True
return func

class Resource(UserDict.DictMixin):
def exposed_attrs(self):
"""attribute names to be exposed as keys"""
return []

def hidden_keys(self):
"""Keys to hide from iteration. A Key will still be accessible if it is
a getter or if it is listed in exposed_attrs()"""
return []

def child_object(self, name):
"""Called to get a child object if it isn't found as a getter or an attribute"""
raise AttributeError

# Dictionary Methods
def __getitem__(self, key):
"""Called to implement evaluation of self[key]"""
getter = getattr(self, 'get_'+key, None)
if hasattr(getter, 'getter'):
return getter()
if key in self.exposed_attrs():
return getattr(self, key)
return self.child_object(key)

def __setitem__(self, key, value):
"""Called to implement assignment to self[key]"""
setter = getattr(self, 'set_'+key, None)
if hasattr(setter, 'setter'):
return setter(value)

def __delitem__(self, key):
"""Called to implement deletion of self[key]"""
deleter = getattr(self, 'del_'+key, None)
if hasattr(deleter, 'deleter'):
return deleter(value)

def keys(self):
"""List of keys for iteration"""
getter_keys = [name.replace('get_', '', 1) for name in dir(self)
if hasattr(getattr(self, name, None), 'getter')]
exposed_keys = getter_keys + self.exposed_attrs()
return [key for key in exposed_keys if key not in self.hidden_keys()]


当继承db.Model时,同时继承Resource:


class PersonModel(Resource, db.Model):
user_id = db.StringProperty()
user_content = db.TextProperty()

@getter
def get_uid(self):
return self.user_id
@getter
def get_content(self):
return self.user_content


在处理请求的时候,再做如下处理:


class RestHandler(webapp.RequestHandler):
def post(self):
self.dispatch_request()

def dispatch_request(self):
self.response.headers["Content-Type"] = "text/plain"
params = {}
for key in self.request.params:
params[str(key)] = self.request.get(key)

obj = //fetch data from PersonModel.
obj = self.preserialize(obj)
out = simplejson.dumps(obj)
self.response.out.write(out)

def translate(self, obj, depth):
return obj

def preserialize(self, obj, depth=0):
obj = self.translate(obj, depth)

if isinstance(obj, datetime.datetime):
return obj.isoformat()
elif isinstance(obj, db.users.User):
return obj.nickname()
elif isinstance(obj, (db.GeoPt, db.IM, db.Key)):
return str(obj)
elif isinstance(obj, types.ListType):
return [self.preserialize(item, depth+1) for item in obj]
elif isinstance(obj, (types.DictType, Resource)):
copy = {}
for key in obj:
copy[key] = self.preserialize(obj[key], depth+1)
return copy
return obj


这个方法不是太好,还有很大的优化空间...

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics