Ordering queryset by distance relative to a given position

半世苍凉 提交于 2019-12-05 15:36:24

Func is new in Django 1.8.

from django.db.models import Func, F

class Sin(Func):
    function = 'SIN'

class Cos(Func):
    function = 'COS'

class Acos(Func):
    function = 'ACOS'

class Radians(Func):
    function = 'RADIANS'

radlat = Radians(latitude) # given latitude
radlong = Radians(longitude) # given longitude
radflat = Radians(F('latitude'))
radflong = Radians(F('longitude'))

Expression = 3959.0 * Acos(Cos(radlat) * Cos(radflat) *
                           Cos(radflong - radlong) +
                           Sin(radlat) * Sin(radflat))

Trader.objects.annotate(distance=Expression).order_by('distance')

Based on this post.

Please note that https://docs.djangoproject.com/en/1.8/ref/models/expressions/#f-expressions "generates SQL" and float("generate sql") does not make sense. "generate sql" == use the value of the field in the generated sql. You would have to change the haversine function with something that knows how to translate itself to sql that does heavy calculations and is friends with django...

You would definitely have to get creative to solve this elegantly. Raw sql seems to be fastest way to get results if you can write the sql to do that calculation. Think about using geo extentions like postgis for example. You can think about precalculation if you have a small and fixed set of input (lat, lon) combinations or "precompute estimations" to be able to limit query result count and calculate and sort in python.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!