简体   繁体   中英

How to serialize ndb.GeoPt for JSON response to fit my needs in Python/Google App Engine

this will be a two part questions,

Here I am sending a GeoPt to my ndb service. Here is what the JSON looks like.

{
    "DriverId": 1,
    "Startpoint": {
        "longitude": 46.764084,
        "latitude": -71.351396
    },
    "Endpoint": {
        "longitude": 46.764084,
        "latitude": -71.351396
    },
    "Regular": false,
    "DateAndTime": "28/03/2015",
    "PlacesAvailable": 3,
    "ValLift": 3
}

I use this function to serialize my DateTimes

def serialiser__json(objet):

    if isinstance(objet, datetime.datetime):
        return objet.replace(microsecond=0).isoformat()
    elif isinstance(objet, datetime.date):
        return objet.isoformat()
    else:
        return objet

Now I am wondering how I could serialize my GeoPt to JSON and return it to look the same as it was sent for example here is my Route model.

class Route(ndb.Model):

  driver_id = ndb.IntegerProperty()
  requester_id = ndb.IntegerProperty()
  startpoint = ndb.GeoPtProperty(required=True)
  endpoint = ndb.GeoPtProperty(required=True)
  regular = ndb.BooleanProperty(required=True)
  date_and_time = ndb.DateTimeProperty(required=True)
  places_available = ndb.IntegerProperty()
  val_lift = ndb.IntegerProperty()

And here is how I add the long lat in my POST definiton

newroute.startpoint = ndb.GeoPt(route_json['Startpoint']['longitude'],route_json['Startpoint']['latitude'])

newroute.endpoint = ndb.GeoPt(route_json['Endpoint']['longitude'],route_json['Endpoint']['latitude'])

So first part,

How would I serialize the GeoPt I have stored in model?

Second part,

How to make it look the same way it was sent (return StartPoint with longitude and latitude "members" inside of it)?

Thanks in advance.

The change you just posted as a self-answer to the body of your peculiarly named serialiser__json (weird to use two adjacent underscores within an identifier, though legal) gives you correct JSON functionality but does not meet your very strict requirement for the "second part":

How to make it look the same way it was sent

There are several problems with that: (A), order of the keys (it's arbitrary when you use a dict , which may result in quite a different "look" of the resulting JSON string, although with equivalent semantics ); (B), whitespace (your incoming JSON string apparently has all sort of beautifying whitespace, including newlines and spaces for indentation purposes); as well as (C), potentially, minor issues with number of significant digits in the formatting of float s.

(A) can be fixed by building up a collections.OrderedDict in the order you want the keys to be -- a json.dumps of that ordered dict will respect the keys' ordering. (B) and (C) are subtler are require more "beautification" work -- do you actually need such cosmetics in your output...?

(All of these problems are pretty much independent of being on App Engine, by the way).

Found how to do it

elif isinstance(objet, ndb.GeoPt):
            return {'longitude': objet.lon, 'latitude': objet.lat  }

The easiest way would be to override the to_dict method of your model. EG:

to_dict(self):
  return {
    "DriverId": self.driver_id,
    "Startpoint": {
        "longitude": self.startpoint.longitude,
        "latitude": self.startpoint.latitude
    },
    "Endpoint": {
        "longitude": self.endpoint.longitude,
        "latitude": self.endpoint.latitude
    },
    "Regular": self.regular,
    "DateAndTime": serialiser__json(self.date_and_time),
    "PlacesAvailable": self.places_available,
    "ValLift": self.val_lift 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM