Search code examples
pythondjango-1.9elasticsearch-dsl

How to serialize Django GeoPt for Elasticsearch


How to define GeoPointField() in elasticsearch django. It shows a serialization error when i am trying to save the instance. i am using library "django_elasticsearch_dsl code:

from django_elasticsearch_dsl.fields import GeoPointField
geolocation = GeoPointField()

when i am trying to save the data

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

it shows error:

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

get_lat_long method

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

Solution

  • The problem is that django_elasticsearch_dsl (and further, elasticsearch_dsl) doesn't know how to serialize that custom django_google_maps.fields.GeoPt object into a format understood by Elasticsearch.

    Quoting the docs, the object will need to have a to_dict() method.

    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.

    You should be able to monkey-patch that method in with something like (dry-coded)

    from django_google_maps.fields import GeoPt
    
    GeoPt.to_dict = lambda self: {'lat': self.lat, 'lon': self.lon}
    

    early in your app's code (an AppConfig ready() method is a good choice, or failing that, a models.py, for instance)