在 Django ORM 中的子查询中返回多个值

Ale*_*ich 7 django django-orm

问题是关于SubqueryDjango ArrayAggORM 的。

\n

例如,我有 2 个模型,彼此之间没有任何关系:

\n
\nclass Example1(models.Model):\n    ident = Integerfield()\n\nclass Example2(models.Model):\n    ident = IntegerField()\n    email = EmailField()\n
Run Code Online (Sandbox Code Playgroud)\n

FK、M2M、O2O 等 2 个模型之间没有连接,但ident两个模型中的字段\n 可能是相同的整数(这在某种程度上是连接),并且通常对于 1 个实例,Example1有多个具有Example2相同的实例ident

\n

我想制作一个subqueryor arrayagg(db Postgres) 或 RAWSQL 之外的任何方式来进行如下注释:

\n
Example1.objects.annotate(\ncls2=Subquery(\nExample2.objects.filter(\nident=OuterRef(\xe2\x80\x98ident\xe2\x80\x99\n).values_list(\xe2\x80\x98email\xe2\x80\x99, flat=True).\n\n#or\n\nExample1.objects.annotate(\ncls2=StringAgg(\nsomething here???, \ndelimeter=\xe2\x80\x99, \xe2\x80\x98,\n distinct=True,)\n\n
Run Code Online (Sandbox Code Playgroud)\n

当然,这不起作用,因为Subquery返回多行,并且似乎不可能使用, StringAgg因为我们在模型之间没有任何连接(没有任何内容可以放入其中 StringAgg)。

\n

有什么想法如何 使用一个查询集中Example1的电子邮件 进行注释吗?Example2

\n

这将在 CASE 表达式中使用。

\n

谢谢...

\n

Bla*_*oor 12

对于 MySQL 后端,您可以使用django-mysql的 GroupConcat ,或者查看帖子自己制作聚合函数:

from django_mysql.models import GroupConcat
Example1.objects.annotate(
    cls2=Subquery(
        Example2.objects.filter(ident=OuterRef('ident')).values('ident')\
        .annotate(emails=GroupConcat('email')).values('emails')
    )
)
Run Code Online (Sandbox Code Playgroud)

对于 PostgreSQL 后端,您可以使用ArrayAgg 或 StringAgg

from django.contrib.postgres.aggregates import ArrayAgg, StringAgg
Example1.objects.annotate(
    cls2=Subquery(
        Example2.objects.filter(ident=OuterRef('ident')).values('ident')\
        .annotate(emails=ArrayAgg('email')).values('emails')
    )
)
# or
Example1.objects.annotate(
    cls2=Subquery(
        Example2.objects.filter(ident=OuterRef('ident')).values('ident')\
        .annotate(emails=StringAgg('email', ',')).values('emails')
    )
)
Run Code Online (Sandbox Code Playgroud)