class Door(ndb.Model):
key = ndb.BlobKeyProperty(required=True)
locked = ndb.BooleanProperty(default=True)
我需要将门转换为字典,如:door.to_dict()
但它没有说:
BlobKeyProperty Reference is not json serializable
我做错了吗?
答案 0 :(得分:3)
您不应该使用key
作为属性名称。 key
是模型密钥的已定义访问器。
答案 1 :(得分:2)
除了蒂姆霍夫曼提到的关于钥匙的部分之外,没有你这样做是正确的(至to_dict()
被认为)。这是一个错误。
如果某个属性无法转换为json,那么您需要将其转换为自己。
例如,日期不能自动转换为json,因为转换后不会知道转换它们的日期格式:
class Door(ndb.Model):
creation_date = ndb.DateTimeProperty(auto_now_add=True)
locked = ndb.BooleanProperty(default=True)
做的:
door.to_dict(exclude=['creation_date'])
然后找到一种方法将日期转换为您需要的格式并将其附加到创建的dict。
答案 2 :(得分:1)
您不应在您的门模型上使用钥匙作为财产。什么是关键参考?一个不同的模型?如果是这样,请使用other_model = ndb.BlobKeyProperty(required = True)。
如果你想在to_dict响应中使用门的密钥,只需覆盖to_dict()方法:
类门(ndb.Model): other_model = ndb.BlobKeyProperty(required = True) locked = ndb.BooleanProperty(默认= True)
def to_dict(self, *args, **kwargs):
d = super(Door, self).to_dict(args, kwargs)
if 'key' not in d:
d['key'] = self.key
return d
如果你这样做是为了返回一个json响应,我发现以下更多用处。编写自己的jsonEncoder。我这样做:
import json
import webapp2
import datetime
import calendar
from google.appengine.ext import ndb
class jsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return calendar.timegm(obj.utctimetuple())
if isinstance(obj, datetime.date):
return calendar.timegm(obj.timetuple())
# If it is a key, return it in it's urlsafe format
elif isinstance(obj, ndb.Key):
return obj.urlsafe()
elif isinstance(obj, ndb.Model):
d = obj.to_dict()
if obj.key is not None:
d['key'] = obj.key.urlsafe()
return d
elif isinstance(obj, list):
pass
elif isinstance(obj, datastore_types.BlobKey):
pass
else:
return json.JSONEncoder.default(self, obj)
然后,我创建了一个JsonHandler:
class JsonHandler(webapp2.RequestHandler):
def initialize(self, request, response):
super(JsonHandler, self).initialize(request, response)
self.response.headers['Content-Type'] = 'application/json'
def render_response(self, **context):
return self.response.write(json.dumps(context, cls=jsonEncoder))
最后,继承JsonHandler:
class DoorHandler(JsonHandler):
def get(self):
door = Door.query().get()
return self.render_response(door=door)
然后您不必覆盖to_dict方法,并且可以处理所有类型的数据。