Django: Рассчитайте среднемесячные расходы на одного пользователя

Учитывая модель Django, которая хранит транзакции пользователей, как я могу создать запрос, который возвращает среднемесячные расходы для каждого пользователя?

Мое текущее решение запрашивает все транзакции, итерирует результат и вычисляет средние значения для каждого пользователя, используя словарь. Я знаю, что есть более эффективный способ запросить это, используя агрегат/аннотацию, но не знаю, как его написать.

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

models.py

Class Transactions(models.Model):
  id = models.AutoField(primary_key=True)
  user = models.ForeignKey('User', on_delete=models.CASCADE)
  amount = models.DecimalField(max_digits=100, decimal_places=2)
  date = models.DateField()

Пробую поздно вечером (не проверено). Код ниже извлекает год и месяц из даты, затем очищает порядок с помощью order_by() (возможно, это не обязательно во всех случаях), затем группирует по 'user', 'year', 'month' и вычисляет среднее значение, сохраняя в столбце с именем 'average' с помощью функции Avg.

Документация имеет несколько других хороших примеров.

from django.db.models.functions import ExtractMonth, ExtractYear
from django.db.models import Avg
...

avg_by_user_by_month = Transactions.objects
                                   .annotate(month=ExtractMonth('date'),
                                             year=ExtractYear('date'),) \
                                   .order_by()\
                                   .values('user', 'year', 'month')\
                                   .annotate(average=Avg('amount'))\
                                   .values('user', 'year', 'month', 'average')
        
Вернуться на верх