Ответ
В Django ORM группировка данных, аналогичная SQL-оператору GROUP BY, выполняется с помощью комбинации методов QuerySet: .values() и .annotate().
**.values('field_name', ...)**: Указывает, по каким полям нужно сгруппировать данные. SQL-аналог:GROUP BY field_name.**.annotate(agg_name=AggregationFunction('field'))**: Добавляет к каждому объекту в QuerySet вычисленное значение (агрегацию), например, количество или сумму. SQL-аналог:COUNT(*),SUM(price).
Важно: Порядок вызова методов имеет значение. Сначала .values() для указания полей группировки, а затем .annotate() для агрегации.
Пример
Допустим, у нас есть модель Product и мы хотим посчитать количество продуктов в каждой категории.
SQL-эквивалент:
SELECT category, COUNT(id) as product_count
FROM products_product
GROUP BY category;
Реализация на Django ORM:
from django.db.models import Count
from myapp.models import Product
# Группируем по полю 'category' и для каждой группы считаем количество записей
products_per_category = Product.objects
.values('category')
.annotate(product_count=Count('id'))
.order_by('-product_count') # Опционально: сортируем по убыванию количества
# Результат будет выглядеть примерно так:
# <QuerySet [{'category': 'Электроника', 'product_count': 150}, {'category': 'Книги', 'product_count': 89}]>
for item in products_per_category:
print(f"Категория: {item['category']}, Количество: {item['product_count']}")
Этот подход позволяет выполнять сложные агрегирующие запросы, оставаясь в рамках Django ORM, без написания сырого SQL.
Ответ 18+ 🔞
О, слушай, а вот эта ваша Django ORM, она же, блядь, как хитрая жопа — вроде всё просто, а потом бац, и ты уже в дебрях. Ну, например, тебе надо сгруппировать данные, как в SQL GROUP BY. Так вот, забудь про сырой SQL, тут свои заморочки есть.
Вот смотри, чтобы сгруппировать, тебе надо два метода в паре использовать: .values() и .annotate(). Это как, блядь, танец такой — один ведёт, другой поддакивает.
**.values('поле_группировки')**— это ты говоришь ORM: «Слушай, группируй вот по этому полю, ясно?». SQL-аналог — тот самыйGROUP BY field_name.**.annotate(название_агрегата=АгрегатнаяФункция('поле'))**— а это уже: «А теперь для каждой полученной группы посчитай мне что-нибудь, например, сколько там записей или сумму нарисуй». Это типаCOUNT(*)илиSUM(price)в SQL.
Вот важный момент, ёпта! Порядок — святое. Сначала всегда .values(), а потом уже .annotate(). Если наоборот сделаешь — получишь пиздец и не тот результат, а потом будешь голову ломать, что пошло не так.
Ну, пример, чтобы совсем понятно стало
Допустим, есть у тебя модель Product (Продукт, ну). И ты хочешь узнать, сколько продуктов в каждой категории валяется. Задача-то проще пареной репы.
Как бы это в SQL выглядело:
SELECT category, COUNT(id) as product_count
FROM products_product
GROUP BY category;
А вот как это на Django ORM делается, без всякого там сырого SQL:
from django.db.models import Count
from myapp.models import Product
# Группируем по полю 'category' и для каждой группы считаем количество записей
products_per_category = Product.objects
.values('category')
.annotate(product_count=Count('id'))
.order_by('-product_count') # Это по желанию — сортируем по убыванию количества, чтобы самые жирные категории сверху были
# Результат будет выглядеть примерно так, QuerySet вернёт:
# <QuerySet [{'category': 'Электроника', 'product_count': 150}, {'category': 'Книги', 'product_count': 89}]>
# Ну и дальше выводишь, как душе угодно
for item in products_per_category:
print(f"Категория: {item['category']}, Количество: {item['product_count']}")
# Выведет что-то вроде:
# Категория: Электроника, Количество: 150
# Категория: Книги, Количество: 89
Вот и вся магия, блядь. Сидишь себе, методы эти вызываешь, и ORM сама всю грязную работу делает — никаких тебе ручных GROUP BY писать не надо. Удобно же, в рот меня чих-пых! Главное — порядок не перепутай, а то будет волнение ебать, где ошибка.