GAE返回JSON数据
Web page通过ajax方式调用web后台的service,返回值为json格式。我个人觉得这样的好处有以下几个方面:
- JSON是轻量级的数据格式,相对于xml来说。
- JSON在web page端可以方便的转为javascript对象,从而更为方面的进行数据的访问。
- JSON格式也方便其他客户端调用,比如手机客户端,从而使web 后台service的重用性大为提高。
之前的项目里用了simplejson(django.utils),现在在网上找到一篇相关的文章:http://stackoverflow.com/questions/2114659/how-to-serialize-db-model-objects-to-json,根据这篇文章提供的json.py,可以很方便的将一个gae里的datastore查询结果转为json格式。经过测试,我发现这段代码有一个问题,即不能处理google.Query对象。为此我加了一段代码,目前使用一切正常。
elif isinstance(obj, db.Query):
return list(obj)
# Copyright 2008 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Utility classes and methods for use with simplejson and appengine. Provides both a specialized simplejson encoder, GqlEncoder, designed to simplify encoding directly from GQL results to JSON. A helper function, encode, is also provided to further simplify usage. GqlEncoder: Adds support for GQL results and properties to simplejson. encode(input): Direct method to encode GQL objects as JSON. """ import datetime from django.utils import simplejson import time from google.appengine.api import users from google.appengine.ext import db 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.Query): 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, 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) def encode(input): """Encode an input GQL object as JSON Args: input: A GQL object or DB property. Returns: A JSON string based on the input object. Raises: TypeError: Typically occurs when an input object contains an unsupported type. """ return GqlEncoder().encode(input)