如何为Elasticsearch序列化Django GeoPt

时间:2018-05-31 05:55:34

标签: python django-1.9 elasticsearch-dsl

如何在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

2 个答案:

答案 0 :(得分:1)

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

引用docs,该对象需要to_dict()方法。

  

我们使用的序列化程序还允许您序列化自己的对象 - 只需在对象上定义to_dict()方法,并在序列化为json时自动调用它。

你应该能够使用(干编码)

这样的方法修补该方法
from django_google_maps.fields import GeoPt

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

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

答案 1 :(得分:0)

问题是get_lat_long()会返回django_google_maps.fields.GeoPt类型的对象,而您无法将{is}分配给您的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()