У меня нет ваших моделей или каких-либо значений, поэтому я не могу проверить, работает ли то, что я говорю.
Я предполагаю, что вы используете Postgres и Django 2.2
Основная проблема в django - проблемы с приведением [Anything]
, когда Anything
не простая строка. Он не работает ни с OuterRef, ни с выражениями F (это то, что я использовал для воспроизведения с более простым запросом)
Итак, я бы использовал функцию для преобразования его в массив непосредственно в Postgres:
from django.db.models import Func
Purpose.objects.annotate(
conversation_count=SubqueryCount(
Conversation.objects.filter(
goal_slugs__contains=Func(
OuterRef("slug"),
function="ARRAY",
template="%(function)s[%(expressions)s]",
)
).values("id")
)
)
В качестве альтернативы, поскольку вы просто проверяете, что значение принадлежит массиву, я бы использовал ANY
в Postgres. Для этого вы можете определить пользовательский поиск:
from django.db.models import Lookup
from django.db.models.fields import Field
class EqualAny(Lookup):
lookup_name = "any"
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
# Notice I reversed right and left here for your example
return "%s = ANY (%s)" % (rhs, lhs), params
# We need to register the lookup here to make sure it happens during the app setup
Field.register_lookup(EqualAny)
Purpose.objects.annotate(
conversation_count=SubqueryCount(
Conversation.objects.filter(goal_slugs__any=OuterRef("slug")).values("id")
)
)
Если вы предоставите модели, я мог бы проверить сгенерированный SQL, чтобы убедиться, что он работает