使用 GeoDjango Distance 对象注释 Django 记录失败
Annotating Django records with GeoDjango Distance objects fails
我有一个带有 GeoDjango GeometryField 的 table,记录包括点和多边形。对于外部 API,我需要 return 那些在距给定点以公里为单位的给定距离内具有点几何的记录。我首先过滤点记录,用距离对象注释那些记录,然后过滤距离。
我发现提供给序列化程序的 filtered
查询集的生成在我的 IDE 中运行良好。但是当我 运行 视图时,它挂在 annotate() 步骤上,并出现此错误:
File "/MyApp/api/views.py", line 102, in get
qs1 = qs0.annotate(distance=Distance('geom', pnt))
TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given
我想不通的是,为什么我可以逐步执行所有行来创建 qs2
,如 qs.count()
和 qs2 排序结果所示,但是当我 运行该代码通过 URL,它在 annotate() 中断。
型号
from django.contrib.gis.db import models as geomodels
class PlaceGeom(models.Model):
place = models.ForeignKey(Place,related_name='geoms')
geom = geomodels.GeometryField(null=True, blank=True, srid=4326)
查看
from django.contrib.gis.geos import Polygon, Point
from django.contrib.gis.measure import D, Distance
class SpatialAPIView(generics.ListAPIView):
def get(self, format=None, *args, **kwargs):
params = self.request.query_params
lon = params.get('lon', None)
lat = params.get('lat', None)
dist = params.get('km', None)
pnt = Point(float(lon), float(lat), srid=4326)
print(dist)
>> 3
qs0 = PlaceGeom.objects.extra(where=["geometrytype(geom) LIKE 'POINT'"])
qs0.count()
>> 1887148
qs1 = qs0.annotate(distance=Distance('geom', pnt))
qs2 = qs1.filter(geom__distance_lte=(pnt, D(km=dist))).order_by('distance')
# results are sorted
print(["{:.4f}".format(p.distance.km) for p in qs2][:5])
>> ['0.0635', '0.1071', '0.1283', '0.4274', '1.0647']
filtered = qs2[:pagesize] if pagesize and pagesize < 200 else qs2[:20]
serial = PlaceSerializer
serializer = serial(filtered, many=True, context={
'request': self.request})
serialized_data = serializer.data
result = {
"count": qs.count(),
"type": "FeatureCollection",
"features": serialized_data
}
return JsonResponse(result, safe=False, json_dumps_params={'ensure_ascii': False, 'indent': 2})
@iain-shelvington在他的评论中正确回答了这个问题。 django.contrib.gs 包的不同部分有两个 Distance 函数。正如错误指示的那样,每个参数的 # of arguments 都是不同的。
django.contrib.gis.db.models.function.Distance
适合此处的 annotate()。
我有一个带有 GeoDjango GeometryField 的 table,记录包括点和多边形。对于外部 API,我需要 return 那些在距给定点以公里为单位的给定距离内具有点几何的记录。我首先过滤点记录,用距离对象注释那些记录,然后过滤距离。
我发现提供给序列化程序的 filtered
查询集的生成在我的 IDE 中运行良好。但是当我 运行 视图时,它挂在 annotate() 步骤上,并出现此错误:
File "/MyApp/api/views.py", line 102, in get
qs1 = qs0.annotate(distance=Distance('geom', pnt))
TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given
我想不通的是,为什么我可以逐步执行所有行来创建 qs2
,如 qs.count()
和 qs2 排序结果所示,但是当我 运行该代码通过 URL,它在 annotate() 中断。
型号
from django.contrib.gis.db import models as geomodels
class PlaceGeom(models.Model):
place = models.ForeignKey(Place,related_name='geoms')
geom = geomodels.GeometryField(null=True, blank=True, srid=4326)
查看
from django.contrib.gis.geos import Polygon, Point
from django.contrib.gis.measure import D, Distance
class SpatialAPIView(generics.ListAPIView):
def get(self, format=None, *args, **kwargs):
params = self.request.query_params
lon = params.get('lon', None)
lat = params.get('lat', None)
dist = params.get('km', None)
pnt = Point(float(lon), float(lat), srid=4326)
print(dist)
>> 3
qs0 = PlaceGeom.objects.extra(where=["geometrytype(geom) LIKE 'POINT'"])
qs0.count()
>> 1887148
qs1 = qs0.annotate(distance=Distance('geom', pnt))
qs2 = qs1.filter(geom__distance_lte=(pnt, D(km=dist))).order_by('distance')
# results are sorted
print(["{:.4f}".format(p.distance.km) for p in qs2][:5])
>> ['0.0635', '0.1071', '0.1283', '0.4274', '1.0647']
filtered = qs2[:pagesize] if pagesize and pagesize < 200 else qs2[:20]
serial = PlaceSerializer
serializer = serial(filtered, many=True, context={
'request': self.request})
serialized_data = serializer.data
result = {
"count": qs.count(),
"type": "FeatureCollection",
"features": serialized_data
}
return JsonResponse(result, safe=False, json_dumps_params={'ensure_ascii': False, 'indent': 2})
@iain-shelvington在他的评论中正确回答了这个问题。 django.contrib.gs 包的不同部分有两个 Distance 函数。正如错误指示的那样,每个参数的 # of arguments 都是不同的。
django.contrib.gis.db.models.function.Distance
适合此处的 annotate()。