[django]通过自定义 aggregate 的方式让 Count 支持 SQL 函数

本文的代码是基于 Django 1.8 的,可能并不适用于其他版本的 Django 。

默认情况下 Count 并不支持 SQL 函数,比如 count(date(field_name)) 。 下面将讲述通过自定义 aggregate 的方式让 count 支持 SQL 函数。

from django.db.models.aggregates import Count
from django.db.models.fields import IntegerField


class CountWithFunc(Count):
    template = '%(function)s(%(distinct)s%(expression)s)'

    def __init__(self, expression, distinct=False, **extra):
        extra.update({'expression': expression})
        super(Count, self).__init__(
            'pk', distinct='DISTINCT ' if distinct else '',
            output_field=IntegerField(), **extra
        )

Event.objects.values('name').annotate(
    count=CountWithFunc("date(created_at)", distinct=True)
)
# == SELECT name, COUNT(DISTINCT date(created_at)) AS count FROM event GROUP BY name

Comments