Сьогодні ми переходимо до наступної важливої частини — QuerySet. Це наш спосіб взаємодії з даними, але не просто взаємодії, а такої, яка робить вас майстром управління даними. Пристебніться, сьогодні буде магія (у її Python-варіанті, звичайно)!
1. Поняття QuerySet в Django ORM
QuerySet — це основа роботи з базою даних у Django. Це, по суті, "набір запитів", який дозволяє вам отримати доступ до даних, що зберігаються у вашій базі. У більш простих термінах, QuerySet — це спосіб сказати Django: "Гей, принеси мені ці записи, а тепер ось ці, а тепер ще відсортуй їх".
Уся взаємодія з базою даних через Django ORM (Object-Relational Mapping) будується саме на QuerySet. Нагадує пошуковий фільтр на сайті інтернет-магазину: ви обираєте лише потрібні параметри (наприклад, "червоні кросівки до 500 у.о."), а QuerySet приносить вам рівно те, що ви запитали.
# Приклад роботи з QuerySet
from myapp.models import Product
# Отримуємо всі записи з моделі Product
products = Product.objects.all()
print(products)
У цьому прикладі objects.all() повертає QuerySet, що містить усі записи моделі Product.
2. Переваги використання QuerySet
Ліниве завантаження даних
Найпотужніша сторона QuerySet — це лінощі. Так-так, не дивуйся, лінь у програмуванні іноді буває чеснотою. QuerySet виконує реальні SQL-запити до бази даних тільки тоді, коли це дійсно необхідно. Це дозволяє уникати зайвого навантаження на базу, скорочуючи кількість запитів.
Приклад лінивого завантаження:
products = Product.objects.all() # Запит до бази ще не відправлено
for product in products: # Тільки тут виконається SQL-запит
print(product.name)
Можливість виконання складних SQL-запитів
За допомогою QuerySet можна складати складні SQL-запити, не знаючи SQL. Django дбає про те, щоб SQL-запити були ефективними та захищеними від ін'єкцій. Наприклад, ти можеш фільтрувати, сортувати і об'єднувати дані у кілька рядків Python-коду.
# Фільтруємо всі продукти, у яких ціна менше 5000
cheap_products = Product.objects.filter(price__lt=5000)
# Сортуємо за іменем
sorted_products = Product.objects.order_by('name')
3. Основні методи QuerySet
Давайте розглянемо популярні методи QuerySet, які вам доведеться використовувати буквально щодня:
| Метод | Опис |
|---|---|
all() |
Повертає всі записи моделі |
filter(**kwargs) |
Повертає записи, що відповідають зазначеним умовам фільтрації |
exclude(**kwargs) |
Повертає записи, які НЕ відповідають зазначеним умовам фільтрації |
get(**kwargs) |
Повертає один запис, що відповідає умовам (якщо записів немає або більше одного — буде помилка) |
order_by(*fields) |
Сортує записи за вказаними полями |
count() |
Повертає кількість записів у QuerySet |
first() і last()QuerySet |
Повертають перший або останній запис у відсортованому |
values(*fields) |
Повертає записи у вигляді словників із зазначеними полями |
distinct() |
Прибирає дублюючі записи (аналог DISTINCT у SQL) |
Приклади роботи з QuerySet
Приклад 1. Отримуємо всі записи
products = Product.objects.all()
for product in products:
print(product.name) # Тут ми виводимо імена всіх продуктів
Запит all() повертає всі записи з таблиці Product. Але будьте обережні: якщо у вас у базі мільйон записів, це може "вбити" ваш сервер (ну, майже). Тому намагайтеся використовувати фільтрацію.
Приклад 2. Фільтрація даних
from datetime import datetime
# Фільтруємо продукти, додані цього місяця
current_month = datetime.now().month
recent_products = Product.objects.filter(created_at__month=current_month)
Тут ми використовуємо магію фільтрації: __month дозволяє вибрати всі записи, створені в поточному місяці. QuerySet підтримує безліч подібних "операторів".
Приклад 3. Робота з одним об'єктом
# Отримуємо конкретний продукт за id
product = Product.objects.get(id=1)
print(product.name)
get() використовується для отримання рівно одного запису. Якщо запису не існує — Django викине виключення DoesNotExist. Якщо записів більше одного — буде помилка MultipleObjectsReturned.
Приклад 4. Сортування
# Сортуємо продукти за ціною (за зростанням)
sorted_products = Product.objects.order_by('price')
# Сортуємо продукти за ціною (за спаданням)
sorted_products_desc = Product.objects.order_by('-price')
Зверніть увагу, що для сортування за спаданням використовується знак мінус -.
Приклад 5. Обмеження вибірки
# Отримуємо лише перші 5 записів
first_five = Product.objects.all()[:5]
Як і в SQL, ви можете обмежити кількість записів за допомогою "зрізів".
Таємничі сили QuerySet: ледача завантаження
QuerySet виконує SQL-запити "ледачо". Це означає, що поки ви не спробуєте отримати дані з QuerySet, жодного запиту до бази не буде. Розглянемо приклад:
products = Product.objects.filter(price__lt=5000)
print(products) # Запиту до бази немає, побачите щось на кшталт: <QuerySet []>
print(list(products)) # Лише тут запит дійсно виконається
Такий підхід дозволяє вам комбінувати ланцюжки операцій (наприклад, фільтрацію та сортування) без виконання проміжних запитів.
Типові помилки при роботі з QuerySet
Під час роботи з QuerySet можна натрапити на кілька поширених помилок:
Помилка при використанні
get(): Якщо запит повертає більше ніж один запис, ви отримаєте виключенняMultipleObjectsReturned. Використовуйтеfilter()у випадках, коли ви не впевнені в кількості записів.Забудете про ліниве завантаження: Якщо ви не викликаєте методи, які "витягують" дані, ви можете не побачити змін або результатів.
Неправильні фільтри: Використовуйте точні оператори фільтрації. Наприклад, для строкових полів використовуйте
__contains,__iexact,__startswith.
Практичне завдання
Створіть модель Book з полями title, author, published_date, і виконайте наступні дії:
- Отримайте всі книги.
- Відфільтруйте книги, опубліковані після 2020 року.
- Знайдіть книгу з конкретною назвою.
- Відсортуйте книги за датою публікації.
- Виведіть лише перші 3 книги з бази.
Спробуйте виконати це в Django Shell, використовуючи команди на кшталт: python manage.py shell.
Тепер ви знаєте, що таке QuerySet, наскільки він "лінивий" і як з ним працювати. У наступній лекції ми дізнаємося, як створювати об'єкти в базі через моделі. До зустрічі! 👋
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ