如何为 JSON 响应序列化 ndb.GeoPt 以满足我在 Python/Google App Engine 中的需求

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

这将是一个两部分的问题,

在这里,我正在向我的 ndb 服务发送一个 GeoPt。这是 JSON 的样子。

{
    "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
}

我使用这个函数来序列化我的 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

现在我想知道如何将我的 GeoPt 序列化为 JSON 和 return 它看起来与发送的一样,例如这里是我的路线模型。

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()

这是我在 POST 定义中添加经纬度的方法

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

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

那么第一部分,

如何序列化存储在模型中的 GeoPt?

第二部分,

如何使其看起来与发送时的方式相同(return 包含经度和纬度 "members" 的起始点)?

提前致谢。

找到了操作方法

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

最简单的方法是覆盖模型的 to_dict 方法。例如:

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 
}

您刚刚发布的更改作为对您特别命名的 serialiser__json 正文的自我回答(在标识符中使用两个相邻的下划线很奇怪,尽管合法)为您提供了正确的 JSON 功能但是 是否满足您对 "second part":

的非常严格的要求

How to make it look the same way it was sent

这有几个问题:(A),键的顺序(当你使用 dict 时它是任意的,这可能会导致结果 JSON 字符串,尽管具有等效的 语义 ); (B),空格(您传入的 JSON 字符串显然具有各种美化空格,包括用于缩进目的的换行符和空格);以及 (C),潜在地,floats.

格式中有效位数的小问题

(A) 可以通过按照您希望键的顺序构建 collections.OrderedDict 来修复 - 该有序字典的 json.dumps 将遵循键的顺序。 (B) 和 (C) 更微妙需要更多 "beautification" 工作——你真的 需要 在你的输出中这样的化妆品......?

(顺便说一下,所有这些问题都与 App Engine 无关)。