Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON serialization of Google App Engine models

I've been searching for quite a while with no success. My project isn't using Django, is there a simple way to serialize App Engine models (google.appengine.ext.db.Model) into JSON or do I need to write my own serializer?

Model:

class Photo(db.Model):     filename = db.StringProperty()     title = db.StringProperty()     description = db.StringProperty(multiline=True)     date_taken = db.DateTimeProperty()     date_uploaded = db.DateTimeProperty(auto_now_add=True)     album = db.ReferenceProperty(Album, collection_name='photo') 
like image 349
user111677 Avatar asked Oct 07 '09 13:10

user111677


2 Answers

A simple recursive function can be used to convert an entity (and any referents) to a nested dictionary that can be passed to simplejson:

import datetime import time  SIMPLE_TYPES = (int, long, float, bool, dict, basestring, list)  def to_dict(model):     output = {}      for key, prop in model.properties().iteritems():         value = getattr(model, key)          if value is None or isinstance(value, SIMPLE_TYPES):             output[key] = value         elif isinstance(value, datetime.date):             # Convert date/datetime to MILLISECONDS-since-epoch (JS "new Date()").             ms = time.mktime(value.utctimetuple()) * 1000             ms += getattr(value, 'microseconds', 0) / 1000             output[key] = int(ms)         elif isinstance(value, db.GeoPt):             output[key] = {'lat': value.lat, 'lon': value.lon}         elif isinstance(value, db.Model):             output[key] = to_dict(value)         else:             raise ValueError('cannot encode ' + repr(prop))      return output 
like image 62
dmw Avatar answered Sep 21 '22 22:09

dmw


This is the simplest solution I found. It requires only 3 lines of codes.

Simply add a method to your model to return a dictionary:

class DictModel(db.Model):     def to_dict(self):        return dict([(p, unicode(getattr(self, p))) for p in self.properties()]) 

SimpleJSON now works properly:

class Photo(DictModel):    filename = db.StringProperty()    title = db.StringProperty()    description = db.StringProperty(multiline=True)    date_taken = db.DateTimeProperty()    date_uploaded = db.DateTimeProperty(auto_now_add=True)    album = db.ReferenceProperty(Album, collection_name='photo')  from django.utils import simplejson from google.appengine.ext import webapp  class PhotoHandler(webapp.RequestHandler):    def get(self):       photos = Photo.all()       self.response.out.write(simplejson.dumps([p.to_dict() for p in photos])) 
like image 34
mtgred Avatar answered Sep 22 '22 22:09

mtgred