Аннотируйте количество моделей по геометрическому пересечению
Проблема
Предполагая эти модели:
class ModelA(models.Model):
geometry = models.PolygonField()
class ModelB(models.Model):
geometry = models.PolygonField()
Как аннотировать к набору запросов ModelA
подсчет пересекающихся экземпляров ModelB
, используя только ORM? Геометрия каждого ModelA
должна пересекаться с геометрией ModelB
экземпляров, а пересекающиеся ModelB
экземпляры подсчитываться.
В конечном итоге я хотел бы order_by
подсчитать количество ModelB
экземпляров и найти ModelA
экземпляры, которые имеют наибольшее количество пересекающихся ModelB
экземпляров.
Что я пробовал
ModelA.objects.annotate(
n_modelb=Count(
ModelB.objects.filter(geometry__intersects=OuterRef("geometry"))
),
)
--> ProgrammingError: subquery must return only one column
ModelA.objects.annotate(
n_modelbSubquery(
ModelB.objects.filter(geometry__intersects=OuterRef("geometry")).count()
),
)
--> ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.
ModelA.objects.annotate(
modelb_ids=Subquery(
ModelB.objects.filter(geometry__intersects=OuterRef("geometry")).values(
"id"
),
),
n_modelb=Count("modelb_ids"),
)
--> CardinalityViolation: more than one row returned by a subquery used as an expression
Связанные вопросы
Я думаю, что в основном я застрял на этом комментарии к этому ответу: https://stackoverflow.com/a/46154553/9778755.
Это решение работает, когда между моделями есть связь. Если вы пытаетесь считать по моделям без отношений, это не работает. - Danielle MadeleyMar 17 '20 at 6:36