Primeiro, você precisa fazer uma Function que possa extrair o mês para você:
from django.db import models
from django.db.models import Func
class Month(Func):
function = 'EXTRACT'
template = '%(function)s(MONTH from %(expressions)s)'
output_field = models.IntegerField()
Depois disso tudo que você precisa fazer é
- anote cada linha com o mês
- agrupe os resultados pelo mês anotado usando
values()
- anote cada resultado com a soma agregada dos totais usando
Sum()
Importante :se sua classe de modelo tiver uma ordenação padrão especificada nas opções meta, você terá que adicionar um
order_by()
vazio cláusula. Isso é por causa de https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by
Campos que são mencionados noorder_by()
parte de um conjunto de consultas (ou que são usados na ordenação padrão em um modelo) são usados ao selecionar os dados de saída, mesmo que não sejam especificados de outra forma novalues()
ligar. Esses campos extras são usados para agrupar resultados “like” e podem fazer com que linhas de resultados idênticas pareçam separadas.
Se você não tiver certeza, basta adicionar o
order_by()
vazio cláusula de qualquer forma, sem quaisquer efeitos adversos. ou seja
from django.db.models import Sum
summary = (Invoice.objects
.annotate(m=Month('date'))
.values('m')
.annotate(total=Sum('total'))
.order_by())
Veja a essência completa aqui:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17
Se precisar de mais informações:
Detalhes sobre como criar suas próprias classes Func:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions
Detalhes sobre a cláusula values(), (preste atenção em como ela interage com annotate() em relação à ordem das cláusulas):https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#values
a ordem na qual as cláusulas annotate() e values() são aplicadas a uma consulta é significativa. Se a cláusula values() preceder a annotate(), a anotação será calculada usando o agrupamento descrito pela cláusula values().