Django 聚合 - 表达式包含混合类型。您必须设置 output_field

Posted

技术标签:

【中文标题】Django 聚合 - 表达式包含混合类型。您必须设置 output_field【英文标题】:Django Aggregation - Expression contains mixed types. You must set output_field 【发布时间】:2016-11-27 12:25:59 【问题描述】:

我正在尝试实现聚合查询,这就是我的代码:

TicketGroup.objects.filter(event=event).aggregate(
                           total_group=Sum(F('total_sold')*F('final_price')))

我在 TicketGroup 对象中有 'total_sold' 和 'final_price' ,我想要做的就是将值相加和相乘,以获得所有 TicketGroups 的总销售量。

我得到的只是这个错误:

表达式包含混合类型。你必须设置 output_field

我做错了什么,因为我将“total_group”称为我的输出字段?

谢谢!

【问题讨论】:

【参考方案1】:

通过output_field Django 表示为Sum 的结果提供字段类型。

from django.db.models import FloatField, F
total_group=Sum(F('total_sold')*F('final_price'), output_field=FloatField())

应该可以解决问题。

【讨论】:

【参考方案2】:

我必须使用不同的东西才能使我的查询正常工作。只是 output_field 不会解决它。我需要两个别名之间的简单划分。这些是两个注释的输出。

from django.db.models import FloatField, ExpressionWrapper, F

distinct_people_with_more_than_zero_bill = Task.objects.filter(
    billable_efforts__gt=0).values('report__title').annotate(
    Count('assignee', distinct=True)).annotate(
    Sum('billable_efforts'))

annotate(yy=ExpressionWrapper(F('billable_efforts__sum') / F('assignee__count'), output_field=FloatField()))

这里的关键是ExpressionWrapper。 没有这个,你会得到一个错误:received non-expression(s)

提示来自 Django 文档本身,它说:

如果您要组合的字段属于不同类型,您将需要 告诉 Django 将返回什么样的字段。由于 F() 不 直接支持 output_field 你需要包装表达式 使用 ExpressionWrapper

链接:https://docs.djangoproject.com/en/2.2/ref/models/expressions/

【讨论】:

以上是关于Django 聚合 - 表达式包含混合类型。您必须设置 output_field的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在单个 SELECT 中混合聚合值和非聚合值?

我得到:“您尝试执行的查询不包含指定表达式'OrdID'作为聚合函数的一部分。我该如何绕过?

混合属性表达式:一对多的多边聚合属性

django字段查询参数及聚合函数

使用SQL语言了解Django ORM中的分组(group by)和聚合(aggregation)查询

Access Query + 您的查询不包含指定表达式“TimeID”作为聚合函数的一部分