我正在尝试注释一个查询集Station
与id
最近邻的Station
使用 Django 2.0.3 和 PostGIS (GeoDjango) 功能。
简化版Station
model:
class Station(models.Model):
name = models.CharField(max_length=128)
location = models.PointField()
objects = StationQuerySet.as_manager()
我遇到的问题是尝试计算最近距离,这涉及注释一个引用子查询location
在外部查询集中。
from django.db.models import OuterRef, Subquery
from django.contrib.gis.db.models.functions import Distance
class StationQuerySet(models.QuerySet):
def add_nearest_neighbour(self):
'''
Annotates each station with the id and distance of the nearest neighbouring station
'''
# Get Station model
Station = self.model
# Calculate distances to each station in subquery
subquery_with_distance = Station.objects.annotate(distance=Distance('location', OuterRef('location')) / 1000)
# Get nearest from subquery
nearest = subquery_with_distance.order_by('distance').values('id')[0]
return self.annotate(
nearest_station_id=Subquery(nearest)
)
线路distance = Station.objects.annotate(distance=Distance('location', OuterRef('location')) / 1000)
结果出现如下错误:
from apps.bikeshare.models import Station
stations = Station.objects.add_nearest_neighbour()
Error:
Traceback (most recent call last):
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2847, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-3-cb35ea6d5d8b>", line 1, in <module>
stations = Station.objects.add_nearest_neighbour()
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/gbrown/Development/transit_bikeshare/apps/bikeshare/querysets.py", line 162, in add_nearest_neighbour
subquery_with_distance = Station.objects.annotate(distance=Distance('location', OuterRef('location')) / 1000)
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/query.py", line 997, in annotate
clone.query.add_annotation(annotation, alias, is_summary=False)
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/sql/query.py", line 975, in add_annotation
summarize=is_summary)
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/expressions.py", line 452, in resolve_expression
c.lhs = c.lhs.resolve_expression(query, allow_joins, reuse, summarize, for_save)
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/contrib/gis/db/models/functions.py", line 58, in resolve_expression
source_fields = res.get_source_fields()
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/expressions.py", line 349, in get_source_fields
return [e._output_field_or_none for e in self.get_source_expressions()]
File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/expressions.py", line 349, in <listcomp>
return [e._output_field_or_none for e in self.get_source_expressions()]
AttributeError: 'ResolvedOuterRef' object has no attribute '_output_field_or_none'