Метод aggregate()

Метод aggregate() предназначен для выполнения агрегаций над QuerySet-ом – то есть вычисления статистических показателей по набору объектов. Часто эти показатели используются для сводных данных: количество, среднее значение, минимум, максимум, сумма, и т.д.

Как это работает:

  1. Вы передаете aggregate() одно или несколько выражений. Выражения могут быть агрегирующими функциями (например, CountSumAvg).
  2. Django вычисляет каждое выражение по QuerySet.
  3. Результат возвращается в виде словаря, где ключ – имя вычисления, а значение – полученный результат.

Note

Если при использовании агрегирующей функции, имя явно не указано, оно будет сгенерировано автоматически. Но если в выражении использовано более сложное условие (например, разность двух агрегирующих функций), то в таком случае обязательно нужно задавать имя самостоятельно.

Пример:

Подсчитать общее количество записей у моделей Blog:

from django.db.models import Count
 
result = Blog.objects.aggregate(total_entries=Count("entry"))
print(result['total_entries'])  # Выведет количество записей

Агрегирующие функции

Общий синтаксис

Параметры

  • expressions (обязательный): Указывает, над какими данными проводить агрегацию. Это могут быть поля модели, их трансформы, или более сложные выражения.
  • output_field (необязательный): Задает тип поля, который должна вернуть функция. Обычно Django определяет его автоматически, но в некоторых случаях его нужно указать вручную.
  • filter (необязательный): Q-объект для фильтрации данных до агрегации.
  • default (необязательный): Задает значение по умолчанию, которое будет использовано, если агрегировать нечего (пустой набор данных). Важно: Count не поддерживает данный аргумент и всегда возвращает 0 при пустом QuerySet.
  • **extra (необязательный): Параметры, передаваемые в итоговый SQL для тонкой настройки.

Пустые группы

Большинство агрегатных функций возвращают None при пустом наборе данных. Count - исключение, возвращает 0при пустом QuerySet.

Avg()

Avg вычисляет среднее арифметическое значение по числовому полю или выражению для QuerySet-а (группы объектов).

Синтаксис:

*class* Avg(*expression*, *output_field=None*, *distinct=False*, *filter=None*, *default=None*, ***extra*)

  • distinct: Необязательный параметр. Если distinct=TrueAvg возвращает среднее значение уникальных значений. По умолчанию равен False.
  • Алиас по умолчанию: field__avg

Возвращаемое значение:

  • Тип возвращаемого значения - float, если входной тип int, иначе тот же тип, что и входное выражение, или output_field, если он указан.
  • Если набор данных или группировка пусты, возвращается значение по умолчанию.

Как использовать:

from django.db.models import Avg
 
# Среднее значение поля price по всем объектам Product:
average_price = Product.objects.**aggregate(avg_price=Avg('price'))**
print(average_price['avg_price'])

Count()

Count возвращает количество объектов, связанных через предоставленное выражение.

Синтаксис:

*class* Count(*expression*, *distinct=False*, *filter=None*, **extra)*

  • distinct: Необязательный параметр. Если distinct=TrueCount подсчитывает только уникальные экземпляры. По умолчанию равен False.
  • параметр default недоступен.
  • Count('*') эквивалентно выражению SQL COUNT(*). Но в случае такого использования обязательно нужно задать имя.
  • Алиас по умолчанию: field__count

Возвращаемое значение:

  • Тип возвращаемого значения - int.

Как использовать:

from django.db.models import Count
 
# Подсчет количества объектов в модели MyModel
num_objects = MyModel.objects.**aggregate(num_objects=Count('*'))**

Max()

Max возвращает максимальное значение из заданного выражения для QuerySet (группы объектов).

Синтаксис:

class Max(expression, output_field=None, filter=None, default=None, **extra)

  • Алиас по умолчанию: field__max

Возвращаемое значение:

  • Тип возвращаемого значения соответствует типу входящего поля, или output_field, если он задан.

Как использовать:

from django.db.models import Max
 
# Нахождение максимального значения поля "age" в модели MyModel
max_age = MyModel.objects.**aggregate(max_age=Max('age'))**

Min()

Min возвращает минимальное значение из заданного выражения для QuerySet (группы объектов).

Синтаксис:

class Min(expression, output_field=None, filter=None, default=None, **extra)

  • Алиас по умолчанию: field__min

Возвращаемое значение:

  • Тип возвращаемого значения соответствует типу входящего поля, или output_field, если он задан.

Как использовать:

from django.db.models import Min
 
# Нахождение минимального значения поля "age" в модели MyModel
min_age = MyModel.objects.**aggregate(min_age=Min('age'))**

Sum()

Sum возвращает сумму значений из заданного выражения для QuerySet (группы объектов).

Синтаксис:

class Sum(expression, output_field=None, distinct=False, filter=None, default=None, **extra)

  • distinct: Необязательный параметр. Если distinct=TrueSum возвращает сумму уникальных значений. По умолчанию равен False.
  • Алиас по умолчанию: field__sum

Возвращаемое значение:

  • Тип возвращаемого значения соответствует тому, что и поле ввода, или output_field, если он задан. Если набор QuerySet пуст, возвращается значение по умолчанию.

Как использовать:

from django.db.models import Sum
 
# Нахождение суммы значений поля "quantity" в модели MyModel
total_quantity = MyModel.objects.**aggregate(total_quantity=Sum('quantity'))**

Метод values()

values() преобразует QuerySet из набора объектов модели в набор словарей. Каждый словарь –это одна “строка”, где ключи являются полями модели, а значения –их данными.

Когда это нужно:

  • Оптимизация: Когда нужны лишь некоторые поля, values() может ускорить запросы, так как Django не будет создавать целые объекты модели.
  • Работа со словарями: Если вам нужны результаты запроса именно как словари, values() - идеальный выбор.
  • Простые преобразования данных: values() облегчает последующие трансформации над данными.

Использование:

values(**fields*, ***expressions*)

Метод values() принимает необязательные позиционные аргументы, *fields, которые указывают имена полей, по которым должен быть ограничен SELECT.

Если вы указываете поля, каждый словарь будет содержать только ключи/значения полей, которые вы указали.

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

Метод values() также принимает необязательные именованные аргументы, **expressions, которые передаются в annotate(

Blog.objects.values("name", "entry__headline")
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>
# Вывод всех полей
blogs_as_dicts = Blog.objects.values() 
 
# Вывод только имени и id
blogs_as_dicts = Blog.objects.values('id', 'name')

Особенности:

  • Если у вас есть поле, которое является ForeignKey, вызов values() по умолчанию вернет ключ словаря с названием field_id.
  • При использовании values() вместе с distinct(), учитывайте, что порядок может влиять на результаты.

Прочие моменты:

  • После вызова values() можно использовать filter()order_by() и т. д.
  • Метод values() позволяет ссылаться на поля в связанных моделях с обратными отношениями через атрибуты OneToOneFieldForeignKey и ManyToManyField.

Пример:

Blog.objects.values("name", **"entry__headline"**)
 
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>

〰〰〰 𓆝 𓆟 𓆞 𓆝 𓆟 𓆝 𓆟 𓆞 〰〰〰