JavaRush /Курси /Модуль 3: Django /Пошук і впорядкування даних в API

Пошук і впорядкування даних в API

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

Сьогодні ми зануримося в дві важливі теми, які зроблять ваш API зручним інструментом для роботи з даними: пошук і впорядкування даних. Ми навчимося додавати можливість пошуку даних за вказаними полями і керувати їх сортуванням за допомогою вбудованих інструментів DRF. Сортування і пошук обов’язкові для сучасних API, адже вони підвищують зручність роботи з даними і гнучкість їх обробки.

Реалізація пошуку даних

Пошук в API дозволяє клієнту передавати певні параметри (наприклад, пошукові рядки), щоб знаходити дані, які відповідають цим параметрам. Наприклад, у вашому API може бути ендпоінт для отримання списку користувачів, і ви хочете шукати користувачів за ім'ям або електронною поштою. Це і є пошук.

Django REST Framework надає вбудований фільтр для реалізації пошуку — SearchFilter. Він дозволяє шукати за вказаними полями моделей через параметри запиту.

Спершу переконаймося, що у нас увімкнено модуль фільтрації. У файлі settings.py переконайтеся, що підключили фільтри в DEFAULT_FILTER_BACKENDS:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
    ]
}

Тепер додамо можливість пошуку в одне з наших представлень. Для прикладу будемо працювати з моделлю Book:

# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    published_date = models.DateField()
    genre = models.CharField(max_length=50)

Налаштуємо ендпоінт, який підтримує пошук за полями title і author. Для цього використаємо вбудований SearchFilter.

# views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework.filters import SearchFilter
from .models import Book
from .serializers import BookSerializer

class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [SearchFilter]
    search_fields = ['title', 'author']

Тепер ви можете шукати книги за заголовком або автором, додаючи параметр search в URL. Наприклад:

GET /api/books/?search=tolstoy

Цей запит поверне всі книги, у назві або авторі яких міститься слово "tolstoy".

DRF обробляє пошуковий рядок як набір слів, об'єднаних логічним АБО. Це означає, що запит ?search=war peace поверне книги, які містять або "war", або "peace".

Сортування даних

Сортування дозволяє впорядковувати об'єкти в результатах запитів. Наприклад, ви можете захотіти відсортувати книги за датою публікації або за алфавітом. API, позбавлене функції сортування, втрачає значну частину своєї гнучкості у роботі з даними.

Для сортування даних DRF надає фільтр OrderingFilter. Він дозволяє клієнту вказувати, за якими полями потрібно сортувати дані. Налаштування відбувається через параметр ordering.

Давайте додамо сортування в наше представлення для роботи з книгами:

# views.py
from rest_framework.filters import SearchFilter, OrderingFilter

class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['title', 'author']
    ordering_fields = ['title', 'published_date']

Тут ми додали OrderingFilter до filter_backends і визначили два поля для сортування: title і published_date.

Тепер клієнт може керувати сортуванням, передаючи параметр ordering у запиті. Наприклад:

  • Сортування за заголовком:

    GET /api/books/?ordering=title
    
  • Сортування за датою публікації у зворотному порядку:

    GET /api/books/?ordering=-published_date
    

Зверніть увагу, що префікс - перед назвою поля вказує на зворотний порядок.

Комбінування пошуку та сортування

Ось тут починається магія! Ви можете комбінувати пошук та сортування в одному запиті. Наприклад:

GET /api/books/?search=love&ordering=published_date

Цей запит поверне список книг, у назві або авторі яких є "love", впорядкований за датою публікації.

Поради з налаштування пошуку і сортування

  1. Обирайте релевантні поля. Не варто додавати всі поля в search_fields або ordering_fields. Залиште тільки ті, які дійсно важливі для користувача.

  2. Перевіряйте продуктивність. Пошук за текстовими полями і сортування за великими наборами даних можуть бути ресурсозатратними операціями. Переконайтеся, що ваша база даних оптимізована.

  3. Кастомізуйте порядок полів. Ви можете вказати значення ordering за замовчуванням, щоб результати автоматично сортувалися за якимось полем:

    class BookViewSet(ModelViewSet):
        queryset = Book.objects.all().order_by('published_date')
        ...
    
  4. Не забувайте про безпеку. Якщо користувачі можуть вводити довільні пошукові рядки, переконайтеся у захисті від SQL-ін'єкцій та інших атак.

Приклад використання в реальному житті

Розглянемо сценарій інтернет-магазину. Ви пропонуєте користувачу можливість шукати продукти за назвою та описом, а потім сортувати результати за ціною або рейтингом.

Для цього вам знадобиться модель Product:

# models.py
class Product(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    rating = models.FloatField()

І відповідне представлення:

# views.py
class ProductViewSet(ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['name', 'description']
    ordering_fields = ['price', 'rating']
    ordering = ['price']  # Сортування за замовчуванням

Тепер клієнт може виконувати такі запити:

  1. Пошук продуктів за ключовими словами:

    GET /api/products/?search=phone
    
  2. Сортування за ціною:

    GET /api/products/?ordering=price
    
  3. Комбінація пошуку і сортування:

    GET /api/products/?search=smartphone&ordering=-rating
    

Типові помилки та їх усунення

Якщо пошук або сортування не працюють, перевірте наступні моменти:

  • Переконайтеся, що фільтри SearchFilter і OrderingFilter додані в filter_backends.
  • Перевірте, що вказані вами поля існують у моделі.
  • Якщо працюєте з великими обсягами даних, переконайтеся, що індексування в базі даних налаштоване для полів пошуку і сортування.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ