Ответ
В Django запросы к базе данных строятся с помощью ORM (Object-Relational Mapping), который позволяет работать с данными как с Python-объектами. Ключевым элементом является QuerySet — объект, представляющий собой "ленивую" коллекцию записей из базы данных.
Основной принцип — ленивая оценка (Lazy Evaluation):
Запрос к базе данных не выполняется до тех пор, пока данные из QuerySet не потребуются явно. Это позволяет эффективно строить сложные запросы, не нагружая базу данных на каждом шаге.
Процесс построения запроса:
-
Получение менеджера модели: Начальная точка для любого запроса — менеджер
objects.from myapp.models import User # Создает базовый QuerySet, который выберет все записи all_users = User.objects.all() -
Фильтрация и chaining (цепочки методов): Методы
filter(),exclude(),order_by()и другие возвращают новыйQuerySet, позволяя объединять их в цепочки.# На этом этапе SQL-запрос еще НЕ выполнен active_admins = User.objects.filter(is_active=True, role='admin').order_by('-date_joined') -
Выполнение запроса (Evaluation):
QuerySetобращается к базе данных только при попытке получить доступ к данным:- Итерация:
for user in active_admins: - Срезы:
active_admins[:5] - Вызов
len(),list(),bool()
- Итерация:
-
Агрегация и аннотация: Для вычислений на стороне БД используются
aggregate()иannotate().from django.db.models import Count # Добавить к каждому пользователю поле с количеством его постов users_with_post_count = User.objects.annotate(post_count=Count('posts'))
Чтобы увидеть, какой SQL-запрос будет сгенерирован, можно использовать свойство query:
print(active_admins.query)
# Вывод: SELECT ... FROM "myapp_user" WHERE ("myapp_user"."is_active" = True AND "myapp_user"."role" = 'admin') ORDER BY "myapp_user"."date_joined" DESC