Django ORM 通过自定义 Func 进行分组

aar*_*cas 5 python django postgresql orm

我正在使用 Django,我需要通过自定义函数对模型进行分组。

好的,我想要的查询是:

SELECT date_trunc('week',"model_table"."date") AS "date" FROM "model_table" GROUP BY "date"
Run Code Online (Sandbox Code Playgroud)

那么我尝试过的如下:

SELECT date_trunc('week',"model_table"."date") AS "date" FROM "model_table" GROUP BY "date"
Run Code Online (Sandbox Code Playgroud)

除了该GROUP BY子句还插入表唯一 id 之外,它还能工作。这意味着最终结果根本没有分组。

我一直在检查 Django 代码,在Query类中有一个函数set_group_by,它把一切搞乱了,但我真的不知道如何破解它。

Func不管怎样,我认为正确的方法是从类继承,而不是继承Aggregate,但是我无法让 DjangotGROUP BY在最终的 SQL 中插入该子句。

知道如何在不使用硬编码查询或直接编写查询的其他方式的情况下解决这个问题cursor吗RawSQL?

aar*_*cas 0

好吧,我找到了一种方法来做到这一点,Func尽管它只是一个补丁。因此,首先创建自定义函数,例如:

class DateTrunc(Func):
    function = 'date_trunc'
    template = "%(function)s('%(date_type)s',%(expressions)s)"
    date_types = ['microsecond', 'millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year', 'decade', 'century', 'millenium']

    def __init__(self, date_type, expression, **extra):
        if date_type not in self.date_types:
            raise AttributeError('The specified "date_type" is not correct.')
        super().__init__(expression, date_type=date_type, **extra)
Run Code Online (Sandbox Code Playgroud)

然后我们有一个简单的自定义函数,我们的查询可以是:

In [7]: Model.objects.annotate(date=DateTrunc('week','date')).values('date').annotate(Avg('parameter')).query.__str__()                                       
Out[7]: 'SELECT date_trunc(\'week\',"model_table"."date") AS "date", AVG("model_table"."parameter") AS "parameter__avg" FROM "model_table" GROUP BY date_trunc(\'week\',"model_table"."date")'
Run Code Online (Sandbox Code Playgroud)

在这个解决方案中,他parameter或聚合函数Avg可以是任何并且不会被使用。只是一个修复,使 Django 按我想要的日期分组。