You would need a custom "to JSON" converter that handles formats not natively supported by JSON.
I am using something like the following code that handles most situations for me.
def to_json(self, o):
if isinstance(o, list):
return [self.to_json(l) for l in o]
if isinstance(o, dict):
x = {}
for l in o:
x[l] = self.to_json(o[l])
return x
if isinstance(o, datetime.datetime):
return o.isoformat()
if isinstance(o, ndb.GeoPt):
return {'lat': o.lat, 'lon': o.lon}
if isinstance(o, ndb.Key):
return o.urlsafe()
if isinstance(o, ndb.Model):
dct = o.to_dict()
dct['id'] = o.key.id()
return self.to_json(dct)
return o
So in my case I am also taking care of some other things like GeoPt, and adding an ID field to all ndb.Models but for your case all you'd need would be:
if isinstance(o, datetime.datetime):
return o.isoformat()
but I am guessing (not really sure) you would then get a key error as well so you'd also need
if isinstance(o, ndb.Key):
return o.urlsafe()
In case if you didn't need the created_at field, you could simply exclude it like
rv = json.dumps(user.to_dict(exclude=['created_at']))