Първо, трябва да създадете функция, която може да извлече месеца вместо вас:
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()
След това всичко, което трябва да направите, е
- Анотирайте всеки ред с месеца
- групирайте резултатите по анотирания месец, като използвате
values()
- Анотирайте всеки резултат с обобщената сума от общите суми, като използвате
Sum()
Важно :ако класът на вашия модел има подреждане по подразбиране, посочено в мета опциите, тогава ще трябва да добавите празен order_by()
клауза. Това е заради https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by
Полета, които са споменати в
order_by()
част от набор от заявки (или които се използват при подреждането по подразбиране на модел) се използват при избора на изходни данни, дори ако не са посочени по друг начин вvalues()
обадете се. Тези допълнителни полета се използват за групиране на резултатите „харесвам“ заедно и могат да направят така, че иначе идентичните редове с резултати да изглеждат отделни.
Ако не сте сигурни, можете просто да добавите празния order_by()
клауза така или иначе без никакви неблагоприятни последици.
т.е.
from django.db.models import Sum
summary = (Invoice.objects
.annotate(m=Month('date'))
.values('m')
.annotate(total=Sum('total'))
.order_by())
Вижте пълния смисъл тук:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17
Ако имате нужда от допълнителна информация:
Подробности за създаването на ваши собствени Func класове:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions
Подробности за клаузата values() (обърнете внимание на това как тя взаимодейства с annotate() по отношение на реда на клаузите):https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#values
редът, в който клаузите annotate() и values() се прилагат към заявка, е важен. Ако клаузата values() предхожда annotate(), анотацията ще бъде изчислена с помощта на групирането, описано от клаузата values().