Appengine中的JSON序列化

來源:互聯網
上載者:User

 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

這個方法不是太好,還有很大的最佳化空間...

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.