Подсчёт количества запросов к базе в Django ORM

Показанный фрагмент не выполняет ни одного SQL-запроса. all() и filter() только создают ленивые QuerySet; чтение БД начнётся при их вычислении.

Короткий ответ

Что ответить на собеседовании

Показанный фрагмент не выполняет ни одного SQL-запроса. all() и filter() только создают ленивые QuerySet; чтение БД начнётся при их вычислении.

Подробный разбор

Ответ с пояснениями

Условие

Определите, сколько SQL‑запросов будет отправлено к базе данных при выполнении следующих операций в Django ORM.

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    name = models.CharField(max_length=255)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
    price = models.IntegerField(default=100)

# Получаем QuerySet со всеми книгами
books_qs = Book.objects.all()

# Фильтруем книги по первому автору
books_by_author1 = books_qs.filter(author_id=1)
# Фильтруем книги по второму автору
books_by_author2 = books_qs.filter(author_id=2)

Проанализируйте, какие запросы будет выполнены при создании books_qs и при каждом из фильтров.

Ответ

Показанный фрагмент не выполняет ни одного SQL-запроса. all() и filter() только создают ленивые QuerySet; чтение БД начнётся при их вычислении.

books_qs описывает все книги. Два вызова filter создают отдельные выборки и не изменяют исходную. Передача author_id=1/2 не загружает объекты Author.

Если затем вызвать list(books_by_author1) и list(books_by_author2), обычно выполнятся два независимых SELECT. Если отдельно вычислить books_qs, появится третий. Кеш результата одного QuerySet не является общим кешем всех его отфильтрованных клонов. Поэтому число запросов определяется последующим использованием, которого в примере пока нет.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее