我有一个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)
此值中的值存储为格式latitude, longitude
的字符串。在我的模板中,我按如下方式传递了一个网址:/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
会返回以相同latitude
开头的所有条目。但是,现在我还要匹配longitude
,这就是为什么我正在运行for loop
并搜索在latitude,longitude
中分隔LocationField
的逗号的索引。 n_string
获取LocationField
的子字符串,然后我计划将其与longitude
变量匹配。
我的问题是两部分:
这是否有django包?
答案 0 :(得分:6)
至少有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)一些聪明的查询(想想广场上的圆圈)
答案 1 :(得分:1)
您应该使用GIS数据库来存储和执行坐标,搜索等操作。
用于存储位置使用https://docs.djangoproject.com/en/dev/ref/contrib/gis/model-api/#pointfield
作为数据库,您可以使用https://docs.djangoproject.com/en/dev/ref/contrib/gis/install/#postgis或https://docs.djangoproject.com/en/dev/ref/contrib/gis/install/spatialite/
要在附近搜索,您应该使用距离查找,请参阅https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-lookups
中的示例答案 2 :(得分:0)