Как в Django ограничить количество объектов в QuerySet

«Как в Django ограничить количество объектов в QuerySet» — вопрос из категории Django, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для ограничения количества объектов в Django QuerySet используется стандартный синтаксис срезов (slicing), аналогичный срезам в списках Python. Это транслируется в SQL-выражения LIMIT и OFFSET, что является наиболее эффективным способом получить нужное количество записей из базы данных.

Примеры:

from myapp.models import Product

# 1. Получить первые 5 продуктов
# SQL: SELECT ... FROM myapp_product LIMIT 5;
first_five = Product.objects.all()[:5]

# 2. Пропустить первые 5 и взять следующие 10 (пагинация)
# SQL: SELECT ... FROM myapp_product LIMIT 10 OFFSET 5;
products_from_6_to_15 = Product.objects.all()[5:15]

# 3. Получить один, самый первый объект (альтернатива .first())
# SQL: SELECT ... FROM myapp_product LIMIT 1;
one_product = Product.objects.all()[:1]

Важные особенности:

  • Ленивость (Laziness): Запрос к базе данных не выполняется в момент создания среза. Он будет выполнен только тогда, когда вы начнете итерироваться по QuerySet или иным образом его "материализуете". Срез лишь добавляет LIMIT/OFFSET к будущему SQL-запросу.

  • Отрицательные срезы не поддерживаются: Попытка использовать отрицательную индексацию, например Product.objects.all()[-5:], вызовет ошибку AssertionError.

    Правильный способ получить последние N записей — это отсортировать QuerySet в обратном порядке и взять срез:

    # Получить 5 последних созданных продуктов
    last_five_products = Product.objects.order_by('-created_at')[:5]