Först måste du skapa en funktion som kan extrahera månaden åt dig:
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()
Efter det är allt du behöver göra
- ange varje rad med månaden
- gruppera resultaten efter den kommenterade månaden med
values()
- kommentera varje resultat med den aggregerade summan av totalsumman med
Sum()
Viktigt :om din modellklass har en standardordning specificerad i metaalternativen, måste du lägga till en tom order_by()
klausul. Detta beror på https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by
Fält som nämns i
order_by()
del av en frågeuppsättning (eller som används i standardordningen på en modell) används vid val av utdata, även om de inte på annat sätt anges ivalues()
ringa upp. Dessa extra fält används för att gruppera "gilla"-resultat och de kan göra att annars identiska resultatrader ser ut att vara separata.
Om du är osäker kan du bara lägga till den tomma order_by()
klausul i alla fall utan några negativa effekter.
dvs.
from django.db.models import Sum
summary = (Invoice.objects
.annotate(m=Month('date'))
.values('m')
.annotate(total=Sum('total'))
.order_by())
Se hela sammanfattningen här:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17
Om du behöver mer information:
Detaljer om hur du skapar dina egna Func-klasser:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions
Detaljer om values()-satsen, (var uppmärksam på hur den interagerar med annotate() med avseende på ordningen på klausulerna):https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#values
ordningen i vilken annotate() och values()-satserna tillämpas på en fråga är signifikant. Om values()-satsen föregår annotate(), kommer annoteringen att beräknas med den gruppering som beskrivs av values()-satsen.