We have an ndb model that we would like to make json serializable. The models are fairly simple along the lines of:
class Pasta(ndb.Model):
   name = ndb.StringProperty()
   type = ndb.StringProperty()
   comments = ndb.JsonProperty()
Then on the handler side we would like to do something along the lines of:
json.dumps(Pasta.query(Pasta.name=="Ravioli").fetch()) and return it to the client, but it keeps throwing json parse errors since the class Pasta is not json serializable. So, the question is, do we have to implement __str__ or __repr__ or is there a niftier way to do it?
ndb.Model instances have a to_dict() function:
https://developers.google.com/appengine/docs/python/ndb/modelclass#Model_to_dict
the simplest way is:
json.dumps([p.to_dict() for p in Pasta.query(Pasta.name == "Ravioli").fetch()])
                        I don't believe it's documented, but for existing ext.db Models, you can use db.to_dict() (see here).
Be careful though with db.ReferenceProperty's and db.DateTimeProperty's as they will throw errors when you call json.dumps(). The quick solution is a custom 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...
Then to encode with this:
JSONEncoder().encode(YourModel.all().fetch())
                        Or you can just add a computed property to the model like below:
class Taxes(ndb.Model):
    name = ndb.StringProperty()
    id = ndb.ComputedProperty(lambda self: self.key.id())
then in your get method just call to_dict and you will get the id
rows = [row.to_dict() for row in Taxes.query()]
self.response.write(json.dumps(rows))
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With