我有一个非常基本的模型:
class Link(models.Model):
title = models.CharField(max_length=250, null=False)
user = models.ForeignKey(User)
url = models.CharField(max_length=250, blank=True, null=True)
link_count = models.IntegerField(default=0)
pub_date = models.DateField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
我可以使用以下方式创建按日期分组的所有条目的列表:
Link.objects.values('pub_date').order_by('-pub_date').annotate(dcount=Count('pub_date'))
这自然会按天分组。但我真正想做的是按月分组。无论如何我可以使用annotate()吗?
非常感谢,
答案 0 :(得分:15)
如果你使用PostgreSQL,可能会有以下工作:
from django.db.models import Count
Link.objects.extra(select={'month': 'extract( month from pub_date )'}).values('month').annotate(dcount=Count('pub_date'))
我不确定其他数据库的可移植性extract
。
答案 1 :(得分:13)
from django.db import connections
from django.db.models import Count
Link.objects.extra(select={'month': connections[Link.objects.db].ops.date_trunc_sql('month', 'pub_date')}).values('month').annotate(dcount=Count('pub_date'))
答案 2 :(得分:3)
要添加,作为使用extra()
的替代方法:自Django 1.8起,您还可以使用条件表达式。
>>> year_overview = Link.objects.filter(pub_date__year=year).aggregate(
jan=Sum(
Case(When(created__month=0, then=1),
output_field=IntegerField())
),
feb=Sum(
Case(When(created__month=1, then=1),
output_field=IntegerField())
),
mar=Sum(
Case(When(created__month=2, then=1),
output_field=IntegerField())
),
apr=Sum(
Case(When(created__month=3, then=1),
output_field=IntegerField())
),
may=Sum(
Case(When(created__month=4, then=1),
output_field=IntegerField())
),
jun=Sum(
Case(When(created__month=5, then=1),
output_field=IntegerField())
),
jul=Sum(
Case(When(created__month=6, then=1),
output_field=IntegerField())
),
aug=Sum(
Case(When(created__month=7, then=1),
output_field=IntegerField())
),
sep=Sum(
Case(When(created__month=8, then=1),
output_field=IntegerField())
),
oct=Sum(
Case(When(created__month=9, then=1),
output_field=IntegerField())
),
nov=Sum(
Case(When(created__month=10, then=1),
output_field=IntegerField())
),
dec=Sum(
Case(When(created__month=11, then=1),
output_field=IntegerField())
),
)
>>> year_overview
{'mar': None, 'feb': None, 'aug': None, 'sep': 95, 'apr': 1, 'jun': None, 'jul': None, 'jan': None, 'may': None, 'nov': 87, 'dec': 94, 'oct': 100}
答案 3 :(得分:3)
我已经读过.extra()
将来会被弃用。他们建议改为使用Func
个对象。还有一个用于提取一个月而不使用痛苦的Case
语句。
from django.db.models.functions import ExtractMonth
Link.objects.all().annotate(pub_date_month=ExtractMonth('pub_date'))