Аннотирование пересечения ГИС во вложенном подзапросе

Я пытаюсь выполнить сложный запрос Django, включающий вложенный подзапрос. Начиная с модели Stick, я хочу аннотировать ownership_pct из модели StickOwnership (что просто, учитывая связь FK). Затем я также хочу аннотировать ownership_pct из модели BoxOwnership таким образом, чтобы связанный с ним Box имел максимальное перекрытие с Stick.

Для справки, вот модели:

Stick:
lateral_line_string = models.LineStringField()

Box:
polygon = models.MultiPolygonField()

BoxOwnership:
box = auto_prefetch.ForeignKey("Box")
owner = auto_prefetch.ForeignKey("Owner")
ownership_pct = DecimalField

StickOwnership:
stick= auto_prefetch.ForeignKey("Stick")
owner = auto_prefetch.ForeignKey("Owner")
ownership_pct = DecimalField

Вот что я написал на данный момент:

from django.db.models import F, OuterRef, Subquery
from django.contrib.gis.db.models.functions import Intersection, Length

sticks = Sticks.objects.all()  # starting queryset is arbitrary
owner_in_question = Owner.objects.first()  # owner is arbitrary

stick_ownership_subquery = StickOwnership.objects.filter(stick=OuterRef('pk'),owner=owner_in_question).only('ownership_pct')

box_subquery = box.objects.filter(polygon__intersects=OuterRef(OuterRef('lateral_line_string'))).annotate(length=Length(Intersection(OuterRef(OuterRef('lateral_line_string')), F('polygon')))).order_by('-length').only('pk')

box_ownership_subquery = BoxOwnership.objects.filter(box=Subquery(box_subquery.first().pk), owner=owner_in_question).only('ownership_pct')

sticks = sticks.annotate(stick_ownership=Subquery(stick_ownership_subquery.values('ownership_pct'))).annotate(box_ownership=Subquery(box_ownership_subquery.values('ownership_pct')))

В box_subquery возникает эта ошибка:

Traceback (most recent call last):
  File "venv/lib/python3.10/site-packages/IPython/core/interactiveshell.py", line 3251, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-8-0b4d9b715187>", line 1, in <module>
    box_subquery = Box.objects.filter(polygon__intersects=OuterRef(OuterRef('lateral_line_string'))).annotate(length=Length(Intersection(OuterRef(OuterRef('lateral_line_string')), F('polygon'))))
  File "venv/lib/python3.10/site-packages/django/db/models/query.py", line 1225, in annotate
    return self._annotate(args, kwargs, select=True)
  File "venv/lib/python3.10/site-packages/django/db/models/query.py", line 1273, in _annotate
    clone.query.add_annotation(
  File "venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1074, in add_annotation
    annotation = annotation.resolve_expression(
  File "venv/lib/python3.10/site-packages/django/contrib/gis/db/models/functions.py", line 71, in resolve_expression
    res = super().resolve_expression(*args, **kwargs)
  File "venv/lib/python3.10/site-packages/django/db/models/expressions.py", line 762, in resolve_expression
    c.source_expressions[pos] = arg.resolve_expression(
  File "venv/lib/python3.10/site-packages/django/contrib/gis/db/models/functions.py", line 74, in resolve_expression
    source_fields = res.get_source_fields()
  File "venv/lib/python3.10/site-packages/django/db/models/expressions.py", line 390, in get_source_fields
    return [e._output_field_or_none for e in self.get_source_expressions()]
  File "venv/lib/python3.10/site-packages/django/db/models/expressions.py", line 390, in <listcomp>
    return [e._output_field_or_none for e in self.get_source_expressions()]
AttributeError: 'OuterRef' object has no attribute '_output_field_or_none'

В результате поиска неисправностей я обнаружил, что проблема заключается в вызове Intersection и использовании OuterRef для одной из геометрий. Когда я подставляю фиктивную геометрию, код работает нормально. Есть ли возможность обойти использование OuterRef для ссылки на поле геометрии?

Вернуться на верх