Сьогодні ми зануримося в дві важливі теми, які зроблять ваш 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", впорядкований за датою публікації.
Поради з налаштування пошуку і сортування
Обирайте релевантні поля. Не варто додавати всі поля в
search_fieldsабоordering_fields. Залиште тільки ті, які дійсно важливі для користувача.Перевіряйте продуктивність. Пошук за текстовими полями і сортування за великими наборами даних можуть бути ресурсозатратними операціями. Переконайтеся, що ваша база даних оптимізована.
Кастомізуйте порядок полів. Ви можете вказати значення
orderingза замовчуванням, щоб результати автоматично сортувалися за якимось полем:class BookViewSet(ModelViewSet): queryset = Book.objects.all().order_by('published_date') ...Не забувайте про безпеку. Якщо користувачі можуть вводити довільні пошукові рядки, переконайтеся у захисті від 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'] # Сортування за замовчуванням
Тепер клієнт може виконувати такі запити:
Пошук продуктів за ключовими словами:
GET /api/products/?search=phoneСортування за ціною:
GET /api/products/?ordering=priceКомбінація пошуку і сортування:
GET /api/products/?search=smartphone&ordering=-rating
Типові помилки та їх усунення
Якщо пошук або сортування не працюють, перевірте наступні моменти:
- Переконайтеся, що фільтри
SearchFilterіOrderingFilterдодані вfilter_backends. - Перевірте, що вказані вами поля існують у моделі.
- Якщо працюєте з великими обсягами даних, переконайтеся, що індексування в базі даних налаштоване для полів пошуку і сортування.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ