Django/Postgres:在 RangeField 上聚合

Posted

技术标签:

【中文标题】Django/Postgres:在 RangeField 上聚合【英文标题】:Django/Postgres: Aggregate on RangeField 【发布时间】:2018-12-16 20:21:22 【问题描述】:

是否可以对DjangoRangeField进行聚合函数?

假设我们有 3 个对象,BigIntegerField price_range

第一个对象:price_range = [10,5000]

第二个对象:price_range = [1,5000]

第三个对象:price_range = [100,9000]

MaxMin 这三个对象的聚合结果将是:

min = 1max = 9000

我正在尝试以这种方式聚合 MaxMin

MyModel.objects.aggregate(Min('price_range'),Max('price_range'),)

这会引发错误:

ProgrammingError: 函数 min(int8range) 不存在第 1 行: SELECT MIN("app_mymodel"."price_range") AS "price_range__min" FROM "app...

【问题讨论】:

如果两者不重叠怎么办?喜欢[1, 5][8, 10] @WillemVanOnsem 没关系。我想得到最低下限和最高上限。 【参考方案1】:

您可以使用Upper(..)Lower(..) 获得范围界限,所以:

from django.db.models.functions import Upper, Lower

MyModel.objects.aggregate(Min(Lower('price_range')), Max(Upper('price_range')))

但请注意,如果范围不重叠(例如 [0, 20][50, 100]),您仍然会得到一个范围 [0, 100]

显然现代版本的 Django 需要将字段命名为 @EricTheise says:

from django.db.models.functions import Upper, Lower

MyModel.objects.aggregate(
    low=Min(Lower('price_range')),
    high=Max(Upper('price_range'))
)

【讨论】:

是的,这正是我想要的。它用于过滤目的。谢谢 感谢几年后遇到这个答案,Django (3.0.6) 给了我一个TypeError: Complex expressions require an alias。在this answer 的指导下,我需要做相当于MyModel.objects.aggregate(lower=Min(Lower('price_range')), upper=Max(Upper('price_range')))

以上是关于Django/Postgres:在 RangeField 上聚合的主要内容,如果未能解决你的问题,请参考以下文章

Django + Postgres:将 JSON 字符串作为 JSON 类型直接保存到模型中

Django Postgres objects.create ValidationError

django、postgres 8.4、psycopg 2.2.2、python 2.7、mod_wsgi

Django Postgres 完整性错误

在 django(postgres 后端)中按数字字符串排序查询结果

为 Django Postgres 连接强制 SSL