22

我们有一个 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__是否有更好的方法来做到这一点?

4

5 回答 5

58

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()])
于 2012-11-09T16:29:36.673 回答
10

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

但要小心db.ReferenceProperty's 和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())
于 2013-09-21T01:56:48.817 回答
1

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

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))
于 2015-08-05T20:00:09.143 回答
0

如果有一个 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 
于 2018-10-25T14:54:37.503 回答
0

如果有一个 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 
于 2018-10-25T15:55:36.613 回答