РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
139 of 818 menu

Класс Sum

Класс Sum применяется в методах aggregate и annotate для вычисления суммы значений числовых полей модели. Он принимает имя поля в качестве аргумента и возвращает выражение, которое преобразуется в SQL-запрос с функцией SUM. При работе с пустыми наборами записей возвращает None, если не указано иное через параметр default.

Синтаксис

from django.db.models import Sum # Использование в агрегации Model.objects.aggregate(Sum('field_name')) # Использование в аннотации Model.objects.annotate(total=Sum('field_name'))

Пример

Рассмотрим модель Order с полями amount и status. Вычислим общую сумму всех заказов:

from django.db import models from django.db.models import Sum class Order(models.Model): amount = models.DecimalField(max_digits=10, decimal_places=2) status = models.CharField(max_length=20) # Создаем несколько заказов Order.objects.create(amount=100.50, status='completed') Order.objects.create(amount=200.75, status='completed') Order.objects.create(amount=50.00, status='pending') res = Order.objects.aggregate(total_amount=Sum('amount')) print(res)

Результат выполнения кода:

{'total_amount': Decimal('351.25')}

Пример

Используем Sum в комбинации с фильтрацией для подсчета суммы только выполненных заказов:

from django.db.models import Sum from myapp.models import Order res = Order.objects.filter(status='completed').aggregate( completed_total=Sum('amount') ) print(res)

Результат выполнения кода:

{'completed_total': Decimal('301.25')}

Пример

Аннотируем каждый заказ дополнительным полем total_related, которое будет содержать сумму связанных позиций через внешний ключ:

from django.db import models from django.db.models import Sum class Order(models.Model): status = models.CharField(max_length=20) class OrderItem(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE) price = models.DecimalField(max_digits=10, decimal_places=2) quantity = models.IntegerField() orders = Order.objects.annotate( total_items=Sum('orderitem__price') ) for order in orders: print(f"Order {order.id}: {order.total_items}")

Результат выполнения кода:

"Order 1: 350.00" "Order 2: 200.00"

Пример

Используем параметр default для замены значения None при отсутствии записей в наборе данных:

from django.db.models import Sum from myapp.models import Order res = Order.objects.filter(status='cancelled').aggregate( cancelled_total=Sum('amount', default=0) ) print(res)

Результат выполнения кода:

{'cancelled_total': 0}

Пример

Вычислим сумму значений с использованием фильтрации через выражение Q для более сложных условий:

from django.db.models import Sum, Q from myapp.models import Order res = Order.objects.aggregate( high_amount_sum=Sum('amount', filter=Q(amount__gt=100)) ) print(res)

Результат выполнения кода:

{'high_amount_sum': Decimal('200.75')}

Смотрите также

  • класс Count,
    который подсчитывает количество записей
  • класс Avg,
    который вычисляет среднее значение по полю
  • класс Min,
    который находит минимальное значение по полю
  • класс Max,
    который находит максимальное значение по полю
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить