Аннотируйте пользователей количеством связанных Purchase, отберите purchase_count > 5 и отсортируйте по убыванию счётчика с ограничением 10. Число покупок не равно сумме count_products.
Топ‑10 пользователей, совершивших более пяти покупок
Аннотируйте пользователей количеством связанных Purchase, отберите purchase_count > 5 и отсортируйте по убыванию счётчика с ограничением 10. Число покупок не равно сумме count_products.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
На основе приведённых моделей необходимо сформировать список из десяти пользователей, у которых количество совершённых покупок превышает пять.
class User(db.Models):
name = models.CharField(
max_length=256,
blank=True,
default="",
verbose_name="Имя"
)
class Product(db.Models):
name = models.CharField(
max_length=256,
blank=True,
default="",
verbose_name="Название"
)
price = models.DecimalField()
class Purchase(db.Models):
user = models.ForeignKey(
model=User,
related_name="purchase",
on_delete=models.CASCADE
)
product = models.ForeignKey(
model=Product,
related_name="purchase",
on_delete=models.CASCADE
)
count_products = models.IntegerField(default=1)
Ответ
Аннотируйте пользователей количеством связанных Purchase, отберите purchase_count > 5 и отсортируйте по убыванию счётчика с ограничением 10. Число покупок не равно сумме count_products.
После исправления объявлений моделей запрос выглядит так:
from django.db.models import Count
top_users = (
User.objects.annotate(purchase_count=Count('purchase'))
.filter(purchase_count__gt=5)
.order_by('-purchase_count', 'id')[:10]
)
Здесь используется related_name='purchase'. Дополнительная сортировка по id делает порядок при равенстве устойчивым. В схеме нужны models.Model, ForeignKey(User, ...), а у DecimalField — max_digits и decimal_places. Если требуется количество единиц товаров, используйте Sum('purchase__count_products'), но это уже другая метрика.