2014-01-23 40 views
0
class Door(ndb.Model): 
    key = ndb.BlobKeyProperty(required=True) 
    locked = ndb.BooleanProperty(default=True) 

我需要門轉換爲字典中:door.to_dict()NDB型號

但它沒有說:

BlobKeyProperty Reference is not json serializable 

難道我做錯了什麼?

回答

2

除了Tim Hoffman提到的有關密鑰的部分之外,不管你做得是否正確(只要認爲是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'])

,然後找到一種方法,將日期轉換爲您需要的格式並將其附加到創建的字典中。

3

您不應該使用key作爲屬性名稱。 key是模型密鑰的已定義訪問器。

1

您不應該使用鑰匙作爲您車門模型的屬性。什麼是關鍵參考?一個不同的模型?如果是這樣,請使用other_model = ndb.BlobKeyProperty(required = True)。

如果你想在你的to_dict響應門的鑰匙,只是覆蓋to_dict()方法:

類門(ndb.Model): other_model = ndb.BlobKeyProperty(所需= TRUE) 鎖定= 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響應,我發現下面更usesful。編寫你自己的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方法將適用於各種數據。

+0

我想我在我的應用程序中使用了與JSON處理程序相同的方法。太好了! –