小编Ema*_*ski的帖子

Django - 从子查询中注释多个字段

我正在处理一个 Django 项目,在该项目上我有一个“A”对象(A.objects.all())的查询集,我需要从“B”对象的子查询中注释多个字段。问题是 annotate 方法只能处理每个参数的一种字段类型(DecimalField、CharField 等),因此,为了注释多个字段,我必须使用类似的方法:

A.objects.all().annotate(b_id          =Subquery(B_queryset.values('id')[:1],
                         b_name        =Subquery(B_queryset.values('name')[:1],
                         b_other_field =Subquery(B_queryset.values('other_field')[:1],
                         ... )
Run Code Online (Sandbox Code Playgroud)

这是非常低效的,因为它为我要注释的每个字段在最终 SQL 上创建了一个新的子查询/子选择。我想在它的 values() 参数上使用具有多个字段的相同子选择,并将它们全部注释在 A 的查询集上。我想使用这样的东西:

b_subquery = Subquery(B_queryset.values('id', 'name', 'other_field', ...)[:1])
A.objects.all().annotate(b=b_subquery)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这样做(并访问第一个元素A.objects.all().annotate(b=b_subquery)[0])时,它引发了一个异常:

{FieldError}Expression contains mixed types. You must set output_field.

如果我设置了Subquery(B_quer...[:1], output_field=ForeignKey(B, models.DO_NOTHING)),我会收到一个数据库异常:

{ProgrammingError}subquery must return only one column

简而言之,整个问题是我有多个“属于”A 的 B,所以我需要使用子查询来为每个 AA.objects.all()选择一个特定的 B 并将其附加到该 A 上,使用 OuterRefs 和一些过滤器(我只想要 B 的几个字段),这对我来说是一个微不足道的问题。

提前感谢您的任何帮助!

python django django-orm django-rest-framework

9
推荐指数
1
解决办法
4078
查看次数