Hi. I am on Django 3.2 using Python 3.8 and Postgres.
I’m trying to annotate the distance between a user and facility. My minimal code is as follows:
User.objects.all().annotate(
test=Subquery(
Facility.objects.annotate(
distance=Distance("facility_address__pnt", OuterRef("user_address__pnt"))
).values("distance")[:1]
)
)
The User and Facility models both have relations to the user_address and facility_address relations respectively. These both have a point attribute which I am attempting to get the distance between.
However this raises an AttributeError which I’ve posted in the stack trace below. I haven’t found anything in the docs that says I shouldn’t be able to do this. Is there something incompatible here with the Geographic functions? Or am I overlooking something simple?
Also, I understand it’s a stupid example, but the query I need this for is a lot more complex.
File ~/xxx/venv/lib/python3.8/site-packages/django/db/models/manager.py:85, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs)
84 def manager_method(self, *args, **kwargs):
---> 85 return getattr(self.get_queryset(), name)(*args, **kwargs)
File ~/xxx/venv/lib/python3.8/site-packages/django/db/models/query.py:1091, in QuerySet.annotate(self, *args, **kwargs)
1086 """
1087 Return a query set in which the returned objects have been annotated
1088 with extra data or aggregations.
1089 """
1090 self._not_support_combined_queries('annotate')
-> 1091 return self._annotate(args, kwargs, select=True)
File ~/xxx/venv/lib/python3.8/site-packages/django/db/models/query.py:1130, in QuerySet._annotate(self, args, kwargs, select)
1128 clone.query.add_filtered_relation(annotation, alias)
1129 else:
-> 1130 clone.query.add_annotation(
1131 annotation, alias, is_summary=False, select=select,
1132 )
1133 for alias, annotation in clone.query.annotations.items():
1134 if alias in annotations and annotation.contains_aggregate:
File ~/xxx/venv/lib/python3.8/site-packages/django/db/models/sql/query.py:1062, in Query.add_annotation(self, annotation, alias, is_summary, select)
1060 """Add a single annotation expression to the Query."""
1061 self.check_alias(alias)
-> 1062 annotation = annotation.resolve_expression(self, allow_joins=True, reuse=None,
1063 summarize=is_summary)
1064 if select:
1065 self.append_annotation_mask([alias])
File ~/xxx/venv/lib/python3.8/site-packages/django/contrib/gis/db/models/functions.py:59, in GeoFuncMixin.resolve_expression(self, *args, **kwargs)
56 res = super().resolve_expression(*args, **kwargs)
58 # Ensure that expressions are geometric.
---> 59 source_fields = res.get_source_fields()
60 for pos in self.geom_param_pos:
61 field = source_fields[pos]
File ~/xxx/venv/lib/python3.8/site-packages/django/db/models/expressions.py:358, in BaseExpression.get_source_fields(self)
356 def get_source_fields(self):
357 """Return the underlying field types used by this aggregate."""
--> 358 return [e._output_field_or_none for e in self.get_source_expressions()]
File ~/xxx/venv/lib/python3.8/site-packages/django/db/models/expressions.py:358, in <listcomp>(.0)
356 def get_source_fields(self):
357 """Return the underlying field types used by this aggregate."""
--> 358 return [e._output_field_or_none for e in self.get_source_expressions()]
AttributeError: 'ResolvedOuterRef' object has no attribute '_output_field_or_none'