JavaRush /Курси /Модуль 3: Django /Фільтрація даних у QuerySet

Фільтрація даних у QuerySet

Модуль 3: Django
Рівень 8 , Лекція 3
Відкрита

Ви вже знаєте, що QuerySet — це потужний інструмент для взаємодії з базою даних у Django. Ми навчилися створювати об'єкти через модель, вони магічно зберігаються у базі — ну майже магічно, адже ми самі все написали. Також ми обговорили, як витягувати дані за допомогою методів all() і працювати з ними. Тепер настав час додати трохи фільтрів — тому що не все, що лежить у базі, вам потрібно, а шукати тільки одне потрібне серед мільйона записів — ну таке собі задоволення.

1. Основи фільтрації

Що таке filter()?

Уявіть, що QuerySet — це як величезне озеро даних. Метод filter() — це той сачок, яким ми обираємо тільки ті дані, які відповідають нашим вимогам. Це основний спосіб відбору даних з бази на рівні ORM.

За допомогою фільтрації ми можемо:

  • Створювати прості запити для відбору за конкретним значенням поля.
  • Задавати складні умови за допомогою операторів.
  • Комбінувати та об'єднувати кілька фільтрів.

Метод filter() повертає новий QuerySet, що містить тільки ті об'єкти, які відповідають умовам фільтрації.

Синтаксис:

Model.objects.filter(<умова>)

Основний принцип: ви передаєте в filter() умови у вигляді ключових аргументів, де ключ — це назва поля моделі, а значення — шукане значення.

Приклад 1: Проста фільтрація

Припустимо, у нас є модель Book:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    publish_year = models.IntegerField()
    is_available = models.BooleanField(default=True)

Тепер ви хочете отримати всі книги автора "Джейн Остін":

from myapp.models import Book

# Отримуємо всі книги автора "Джейн Остін"
books_by_jane_austen = Book.objects.filter(author="Джейн Остін")

Змінна books_by_jane_austen містить всі книги, у яких у полі author вказано "Джейн Остін".

Використання операторів фільтрації

Django ORM надає зручні оператори фільтрації, які можуть бути застосовані до значень полів. Наприклад:

Оператор Опис Приклад використання
__exact Точний збіг author__exact="Джейн Остін"
__iexact Точний збіг без врахування регістру author__iexact="джЕйн ОстІн"
__contains Перевірка, чи містить поле підрядок title__contains="Гордість"
__icontains Те ж саме, але без врахування регістру title__icontains="гордість"
__gte Більше або дорівнює publish_year__gte=2000
__lte Менше або дорівнює publish_year__lte=1999
__in Збіг з одним із вказаних значень author__in=["Джейн Остін", "Толстой"]
__isnull Перевірка на NULL is_available__isnull=True

Приклад 2: Використання операторів

  1. Співпадіння за частиною рядка:

Ми хочемо знайти всі книги, у назві яких є слово "Гордість":

books_with_pride = Book.objects.filter(title__icontains="гордість")
  1. Фільтрація за діапазоном:

Ми шукаємо книги, опубліковані після 2000 року:

recent_books = Book.objects.filter(publish_year__gte=2000)
  1. Перевірка на NULL:

Іноді поле може бути порожнім (наприклад, автор невідомий). Щоб знайти такі записи:

books_with_unknown_author = Book.objects.filter(author__isnull=True)

Складні умови фільтрації

Що робити, якщо ти хочеш об'єднати кілька умов? Наприклад, треба знайти книги, у яких автор "Джейн Остін" і назва містить "розум".

Комбінування умов з filter()

При використанні кількох умов в одному виклику filter() вони об'єднуються за допомогою логічного оператора І.

books_by_jane_and_reason = Book.objects.filter(
    author="Джейн Остін",
    title__icontains="розум"
)

Цей запит поверне книги, що задовольняють обом умовам.

Використання Q-об'єктів для складних умов

Іноді тобі потрібно створити більш складний запит, наприклад:

  • - Знайти книги, у яких автор "Джейн Остін" або назва містить "розум".

Для таких випадків використовується клас Q із django.db.models.

Робота з Q

За допомогою Q можна комбінувати умови за допомогою операторів І & та АБО |.

from django.db.models import Q

books_by_jane_or_reason = Book.objects.filter(
    Q(author="Джейн Остін") | Q(title__icontains="розум")
)

Зверни увагу, що тут логічне АБО (|) об'єднує обидві умови.

Приклад: заперечення умови

За допомогою ~ (тильди) можна заперечувати умову. Наприклад, якщо хочеш виключити книги автора "Джейн Остін":

not_by_jane = Book.objects.filter(~Q(author="Джейн Остін"))

Кращі практики при фільтрації

  • Використовуйте ліниве завантаження QuerySet: QuerySet не виконує запит до бази даних одразу. Це дозволяє вам додавати фільтри та змінювати запит до його явного виконання.

  • Оптимізуйте складні запити: якщо ви використовуєте багато умов, переконайтеся, що вони виконуються ефективно. Використовуйте вбудовані методи Django, такі як select_related() або prefetch_related(), якщо працюєте із пов'язаними об'єктами.

  • Не бійтеся експериментувати! ORM Django дружня і прощає багато ваших експериментів. Тільки не використовуйте продакшн-супутники для таких експериментів.

Практика

Завдання 1: фільтрація записів

  1. Створіть модель Movie з полями:

    • title (рядок)
    • genre (рядок)
    • release_year (ціле число)
    • rating (дробове число)
  2. Заповніть базу даних щонайменше 5 фільмами.

  3. Виконайте наступні запити:

    • Знайдіть всі фільми жанру "комедія".
    • Знайдіть всі фільми, випущені до 2000 року.
    • Знайдіть фільми з рейтингом вище 8.0.
    • Знайдіть фільми, жанр яких починається з літери "д".

Завдання 2: поєднання умов

Для моделі Movie:

  • Знайдіть всі фільми, жанр яких "комедія" або рейтинг більше 9.0.
  • Виключіть фільми, випущені раніше 2010 року.

Підказка: використовуйте Q-об'єкти.

Тепер ви знаєте, як ефективно фільтрувати дані у Django ORM! Готуйтеся, попереду ще більше можливостей!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ