2012-11-09 14 views
19

Abbiamo un modello ndb che vorremmo rendere serializzabile json. I modelli sono piuttosto semplici lungo le linee di:AppEngine Realizzazione di modelli ndb jSON serializzabile

class Pasta(ndb.Model): 
    name = ndb.StringProperty() 
    type = ndb.StringProperty() 
    comments = ndb.JsonProperty() 

Poi sul lato gestore che vorremmo fare qualcosa sulla falsariga di:

json.dumps(Pasta.query(Pasta.name=="Ravioli").fetch()) e restituirlo al cliente, ma mantiene gettando JSON errori di analisi dal momento che la classe Pasta non è serializzabile json. Quindi, la domanda è: dobbiamo implementare __str__ o __repr__ o c'è un modo più efficace per farlo?

+4

Dai un'occhiata a questo: http://stackoverflow.com/questions/1531501/json-serialization-of-google-app-engine-models –

+1

Doggone. Grazie. Non riesco quasi mai a trovare queste domande quando le cerco. – rdodev

+0

NP. È per DB ma non dovrebbe essere un grosso problema da convertire. –

risposta

48

ndb.Model casi hanno una funzione to_dict(): https://developers.google.com/appengine/docs/python/ndb/modelclass#Model_to_dict

il modo più semplice è:

json.dumps([p.to_dict() for p in Pasta.query(Pasta.name == "Ravioli").fetch()]) 
+0

Aweosme. Ciò rende la nostra vita più semplice e più pulita del codice :) – rdodev

+10

Probabilmente è importante notare che 'to_dict' non include la chiave' nel modello. Quindi potresti voler fare qualcosa come 'json.dumps ([dict (p.to_dict(), ** dict (id = p.key.id())) per p in ...' –

+5

Questo dà errore se ci è datetime – Kishan

9

non ritengo è documentato, ma per esistenti ext.db modelli, è possibile utilizzare db.to_dict() (vedi here).

Attenzione però con db.ReferenceProperty e db.DateTimeProperty come faranno errori quando si chiama json.dumps(). La soluzione rapida è un JSONEncoder personalizzato:

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... 

Poi per codificare con questo:

JSONEncoder().encode(YourModel.all().fetch()) 
1

oppure si può semplicemente aggiungere una proprietà calcolata al modello come qui di seguito:

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

poi nel tuo metodo get basta chiamare to_dict e riceverai l'id

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