Аннотируйте количество моделей по геометрическому пересечению
Проблема
Предполагая эти модели:
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