繁体   English   中英

AppEngine使ndb模型json可序列化

[英]AppEngine Making ndb models json serializable

我们有一个ndb模型,我们想让json序列化。 这些模型非常简单:

class Pasta(ndb.Model):
   name = ndb.StringProperty()
   type = ndb.StringProperty()
   comments = ndb.JsonProperty()

然后在处理程序方面,我们想做一些事情:

json.dumps(Pasta.query(Pasta.name=="Ravioli").fetch())并将其返回给客户端,但它不断抛出json解析错误,因为类Pasta不是json可序列化的。 所以,问题是,我们必须实现__str____repr__还是有更__repr__方法呢?

ndb.Model实例具有to_dict()函数: https//developers.google.com/appengine/docs/python/ndb/modelclass#Model_to_dict

最简单的方法是:

json.dumps([p.to_dict() for p in Pasta.query(Pasta.name == "Ravioli").fetch()])

我不相信它已被记录,但对于现有的ext.db模型,您可以使用db.to_dict() (参见此处 )。

使用db.ReferencePropertydb.DateTimeProperty要小心,因为当你调用json.dumps()时它们会抛出错误。 快速解决方案是自定义JSONEncoder:

from datetime import datetime, date, time
from google.appengine.ext import db

import json

class JSONEncoder(json.JSONEncoder):

    def default(self, o):
        # If this is a key, you might want to grab the actual model.
        if isinstance(o, db.Key):
            o = db.get(o)

        if isinstance(o, db.Model):
            return db.to_dict(o)
        elif isinstance(o, (datetime, date, time)):
            return str(o)  # Or whatever other date format you're OK with...

然后用这个编码:

JSONEncoder().encode(YourModel.all().fetch())

或者您可以像下面一样向模型添加计算属性:

class Taxes(ndb.Model):
    name = ndb.StringProperty()
    id = ndb.ComputedProperty(lambda self: self.key.id())

然后在你的get方法中只需调用to_dict,你就会获得id

rows = [row.to_dict() for row in Taxes.query()]
self.response.write(json.dumps(rows))

如果有一个ndb.KeyProperty引用不同的模型,你可以很好地覆盖字典方法,如下所示

def to_dict(self):
        result = super(Point, self).to_dict()
        result['x']=self.x.get().to_dict()
        result['y']=self.y.get().to_dict()
        return result

如果ndb.KeyProperty是一个列表(重复设置为True),请使用以下方法使用get_multi获取引用的模型

def to_dict(self):
       result = super(Figure, self).to_dict()
       result['points']=[p.to_dict() for p in ndb.get_multi(self.points)]
       return result 

如果有一个ndb.KeyProperty引用不同的模型,你可以很好地覆盖字典方法,如下所示

def to_dict(self):
        result = super(Point, self).to_dict()
        result['x']=self.x.get().to_dict()
        result['y']=self.y.get().to_dict()
        return result

如果ndb.KeyProperty是一个列表(重复设置为True),并且如果您打算序列化引用的模型,请使用以下方法使用get_multi获取引用的模型

def to_dict(self):
       result = super(Figure, self).to_dict()
       result['points']=[p.to_dict() for p in ndb.get_multi(self.points)]
       return result 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM