如何为 Elasticsearch 序列化 Django GeoPt

How to serialize Django GeoPt for Elasticsearch

如何在 elasticsearch django 中定义 GeoPointField()。当我尝试保存实例时,它显示序列化错误。我正在使用图书馆“django_elasticsearch_dsl 代码:

from django_elasticsearch_dsl.fields import GeoPointField
geolocation = GeoPointField()

当我尝试保存数据时

 user = GutitUser.objects.get(phone_number=phone_number)
 lat, lon = get_lat_long()
 user.geolocation.lat = lat
 user.geolocation.lon = lon
 user.save()

显示错误:

 "Unable to serialize <django_google_maps.fields.GeoPt object at 0x7f5ac2daea90>
 (type: <class 'django_google_maps.fields.GeoPt'>

get_lat_long方法

def get_lat_long(request):
    ip = json.loads(requests.get('https://api.ipify.org?format=json').text)['ip']

    lat, lon = GeoIP().lat_lon(ip)
    return lat, lon

问题是 django_elasticsearch_dsl(还有 elasticsearch_dsl)不知道如何将该自定义 django_google_maps.fields.GeoPt 对象序列化为 Elasticsearch 可以理解的格式。

引用 docs,对象需要有一个 to_dict() 方法。

The serializer we use will also allow you to serialize your own objects - just define a to_dict() method on your objects and it will automatically be called when serializing to json.

您应该能够使用类似(干编码)

的方法对该方法进行猴子修补
from django_google_maps.fields import GeoPt

GeoPt.to_dict = lambda self: {'lat': self.lat, 'lon': self.lon}

在您的应用程序代码的早期(AppConfig ready() 方法是一个不错的选择,如果失败,例如 models.py

问题是 get_lat_long() returns 一个 django_google_maps.fields.GeoPt 类型的对象,您不能将其分配给 geolocation 对象。但是像下面这样修改代码可能会成功:

 user = GutitUser.objects.get(phone_number=phone_number)
 geo_point = get_lat_long()
 user.geolocation.lat = geo_point.lat
 user.geolocation.lon = geo_point.lon
 user.save()