Appengine制作NDB模型JSON可序列化



我们有一个NDB模型,我们希望使JSON可序列化。这些模型沿着:

的行很简单。
class Pasta(ndb.Model):
   name = ndb.StringProperty()
   type = ndb.StringProperty()
   comments = ndb.JsonProperty()

然后在处理程序侧,我们想按照以下方式进行操作:

json.dumps(Pasta.query(Pasta.name=="Ravioli").fetch())并将其退还给客户端,但是由于类意大利面并且不可序列化,因此它会不断丢弃JSON解析错误。因此,问题是,我们是否必须实现__str____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.ReferenceProperty的和db.DateTimeProperty s,请小心,因为他们在调用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())

然后,在您的获取方法中,请致电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 

最新更新