我有一个
django模型,它有一个名为LocationField的自定义属性.
class List(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=200)
location = LocationField(blank=True, max_length=255)
其中的值存储为纬度,经度格式的字符串.从我的模板中,我传递了一个URL如下:/ nearby?lat =’somevalue’& long =’somevalue
现在,我想从List返回附近的条目,具体取决于传递的值.
为此,我编写了一个views.py函数,如下所示:
def nearby(request):
if request.GET['lat']:
lat = request.GET['lat']
longitude = request.GET['long']
first_query = Playlist.objects.filter(location__istartswith=lat)
for f in first_query:
l = f.index(',')
n_string = f[l:]
为了澄清我所做的事情,first_query返回以相同纬度开头的所有条目.但是,现在我还想匹配经度,这就是我运行for循环的原因,并搜索在我的LocationField中分隔纬度,经度的逗号索引. n_string获取LocationField的子字符串,然后我计划将它与我的经度变量匹配.
我的问题是两部分:
>如何生成匹配纬度的查询以及如何将其返回到模板?
>如何检查该区域周围2平方公里的区域?
这有django套餐吗?
最佳答案 至少有3种方法可以做到这一点:
a)Haersine距离(例如在MySQL中)
def nearby_spots_old(request, lat, lng, radius=5000, limit=50):
"""
WITHOUT use of any external library, using raw MySQL and Haversine Formula
http://en.wikipedia.org/wiki/Haversine_formula
"""
radius = float(radius) / 1000.0
query = """SELECT id, (6367*acos(cos(radians(%2f))
*cos(radians(latitude))*cos(radians(longitude)-radians(%2f))
+sin(radians(%2f))*sin(radians(latitude))))
AS distance FROM demo_spot HAVING
distance < %2f ORDER BY distance LIMIT 0, %d""" % (
float(lat),
float(lng),
float(lat),
radius,
limit
)
queryset = Spot.objects.raw(query)
serializer = SpotWithDistanceSerializer(queryset, many=True)
return JSONResponse(serializer.data)
b)使用Geodjango(PostgreSQL PostGIS)
def nearby_spots_new(request, lat, lng, radius=5000, limit=50):
"""
WITH USE OF GEODJANGO and POSTGIS
https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-queries
"""
user_location = fromstr("POINT(%s %s)" % (lng, lat))
desired_radius = {'m': radius}
nearby_spots = Spot.objects.filter(
mpoint__distance_lte=(user_location, D(**desired_radius))).distance(
user_location).order_by('distance')[:limit]
serializer = SpotWithDistanceSerializer(nearby_spots, many=True)
return JSONResponse(serializer.data)
c)一些聪明的查询(想想广场上的圆圈)