在Django中按月/年注释(组)日期

时间:2014-02-17 19:03:49

标签: django django-models aggregate-functions django-orm

使用Django DateQuerySet我从item查询中提取Group个对象的相关年份。

>>> Group.objects.all().dates('item__date', 'year')
[datetime.date(1990, 1, 1), datetime.date(1991, 1, 1), ...(remaining elements truncated)...']

现在我想在这些日期按不同年份进行计算。我认为这样可行:

>>> Group.objects.all().dates('item__date', 'year').annotate(Count('year'))
FieldError: Cannot resolve keyword 'year' into field.

但看起来我错过了一些东西。如何解决此问题?

我也试过这个问题:

>>> (Group
     .objects
     .all()
     .extra(select=
         {'year': 
          connections[Group.objects.db].ops.date_trunc_sql('year', 'app_item.date')}))
ProgrammingError: missing FROM-clause entry for table "app_item" LINE 1: SELECT (DATE_TRUNC('year', app_item.date)) AS...

但这也不起作用。

2 个答案:

答案 0 :(得分:20)

对于在django 1.9之后发现这个的人,现在有一个TruncDate(TruncMonth,TruncYear)可以做到这一点。

from django.db.models.functions import TruncDate

(Group.objects.all().annotate(date=TruncDate('your_date_attr')
                    .values('date')
                    .annotate(Count('items'))

希望它有所帮助。

答案 1 :(得分:10)

尝试以下几点:

from django.db.models import Count

Item.objects.all().\
        extra(select={'year': "EXTRACT(year FROM date)"}).\
        values('year').\
        annotate(count_items=Count('date'))

您可能希望使用item_instance._meta.fields而不是在那里的MySQL语句中手动指定“date”...

另外,请注意,为了简单起见,我首先使用Item QuerySet而不是Group。应该可以过滤Item QuerySet来获得所需的结果,或者使MySQL的extra位更复杂。

修改

这可能有用,但在依赖它之前我肯定会测试它的内容:)

Group.objects.all().\
    values('item__date').\
    extra(select={'year': "EXTRACT(year FROM date)"}).\
    values('year').\
    annotate(count=Count('item__date'))