Суммировать числа и группировать их по заданному месяцу, есть ли "лучшая практика"?

Я не знаю, что я испортил.

Я пробовал так много методов и решений, и пока это работает лучше всего, но упорядочивание беспорядочно. Я хочу суммировать расходы, сгруппированные по месяцу, извлеченному из поля даты, которое было задано.

На данный момент я сделал следующее:

def index(req):
    qs = Expense.objects.filter(pom='OUT').annotate(month=TruncMonth('when')).values('month').annotate(total_amount=Sum('amount')) # pom='OUT' -- expense (there are expenses and incomes)
    return render(req, 'index.html', {'data': qs})

, который работает отлично, возвращает их как "sept. 15.000, aug. 10.000", что очень хорошо! Но последний/последний месяц всегда внизу, поэтому я хотел дать ему order_by, который возвращает каждый уникальный объект в модели (так что если sept. 15.000 появятся как sept.15 10.000 и sept.22 5.000, когда они не суммируются, а возвращаются/показываются отдельно).

Что я испортил?

EQ: Упомянутый запрос (без order_by) возвращает набор запросов по состоянию на <QuerySet [{'month': datetime.date(2022, 8, 1), 'total_amount': 15000.0}, {'month': datetime.date(2022, 9, 1), 'total_amount': 16000.0}]> по умолчанию создается впечатление, что все они были записаны в начале данного месяца.

Напишите ответ для получения дополнительной информации, если я что-то забыл включить или плохо объяснил!

Попробуйте это:

Expense.objects.filter(pom='OUT')\
    .values('when__year', 'when__month')\
    .annotate(total_amount=Sum('amount'))\
    .order_by('-when__year','-when__month')

Я включил год, иначе он добавит общую_сумму месяцев следующего года к месяцам этого года. Удалите -, если вам нужен возрастающий порядок.

Это даст результат типа:

<QuerySet [
    {'when__year': 2022, 'when__month':9, 'total_amount': 15000.0}, 
    {'when__year': 2022, 'when__month':8, 'total_amount': 16000.0}
]>

Редактирование:

Expense.objects.filter(pom='OUT')\
    .values(
        year=models.F('when__year'), 
        month=models.F('when__month')
    ).annotate(total_amount=Sum('amount'))\
    .order_by('-year','-month')

В результате получится:

<QuerySet [
    {'year': 2022, 'month':9, 'total_amount': 16000.0}, 
    {'year': 2022, 'month':8, 'total_amount': 15000.0}
]>
Вернуться на верх