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

Yuv*_*dam 10 django aggregate-functions django-models django-orm

使用Django DateQuerySet我会itemGroup查询中提取相关年份.

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

现在我想在这些日期按不同的年份进行计数.我认为这会奏效:

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

但看起来我错过了一些东西.我该如何修复此查询?

我也试过这个查询:

>>> (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...
Run Code Online (Sandbox Code Playgroud)

但这也不起作用.

小智 23

对于任何在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'))
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

  • 从我所看到的@mycroft,这是在1.10中添加的 (3认同)

frn*_*nhr 11

尝试这些方面:

from django.db.models import Count

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

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

另外,请注意,为了简单起见,我开始使用ItemQuerySet而不是Group.应该可以过滤ItemQuerySet以获得所需的结果,或者使extraMySQL 的位更复杂.

编辑:

这可能会奏效,但在依赖它之前我绝对会测试它的内容:)

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