2012-11-09 24 views
19

我們有一個ndb模型,我們想讓json可序列化。該模型是沿着線相當簡單:AppEngine製作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

看看這個:http://stackoverflow.com/questions/1531501/json-serialization-of-google-app-engine-models –

+1

Doggone它。謝謝。當我搜索它們時,我幾乎找不到這些問題。 – rdodev

+0

NP。這是數據庫,但應該沒有什麼大不了的。 –

回答

48

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()]) 
+0

Aweosme。這使我們的生活變得更簡單,代碼更清潔:) – rdodev

+10

可能值得注意的是'to_dict'不包含模型中的'key'。所以你可能希望做一些像'json.dumps([dict(p.to_dict(),** dict(id = p.key.id()))for p in ...' –

+5

這會給出錯誤如果有是日期時間 – Kishan

9

我不相信它的記錄,但對於現有ext.db模型,你可以使用db.to_dict()(見here )。

請注意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()) 
1

或者你可以只是一個計算的屬性添加到模型如下圖所示:

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

然後在你的get方法中,只需調用to_dict,你將得到編號

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