Ленивые запросы к базе данных
Когда вы пишете запрос на чтение в Django, на самом деле, он не исполняется сразу же. Звучит странно, но строчка Post.objects.all()
не шлёт никакие запросы в БД. Запросы в Django ORM ленивые и они не отправляются до тех пор, пока их не запустят (в англоязычных текстах это называют evaluate).
В этой статье мы воспользуемся моделью Post
в блоге. У него есть заголовок и текст:
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
Обратите внимание, что запросы на создание или удаление запускаются сразу:
created_post = Post.objects.create(title="Новый пост", text="Текст нового поста")
created_post.delete()
Но если это запрос на чтение, то сколько бы вы ни уточняли запрос, он не запустится и не пойдёт в БД:
posts = Post.objects.all()
posts_by_alphabet = posts.order_by("title")
posts_about_harry_potter = Post.objects.filter(title__icontains="Гарри Поттер")
Все эти строчки ничего не делают в БД, пока вы не попытаетесь ими воспользоваться:
for post in posts_by_alphabet:
print(post.title)
Как посмотреть когда запрос запустился
Это можно посмотреть в Django Debug Toolbar. Он показывает на каких строчках какие запросы запустились. Вот статья как им пользоваться.
Примеры кода, которые запускают запрос
В документации перечислены все способы, мы перечислим только несколько частых примеров:
- Итерация в цикле:
posts = Post.objects.all() for post in posts: ...
- Получение одной записи
post = Post.objects.get(id=1)
- Превращение Queryset в список через
list()
posts = list(Post.objects.all())
- Вызов
len()
posts_amount = len(Post.objects.all())
Не делайте так, используйте
.count()