Сегодня мы погрузимся в две важные темы, которые сделают ваш 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. - Проверьте, что указанные вами поля существуют в модели.
- Если работаете с большими объемами данных, убедитесь, что индексирование в базе данных настроено для полей поиска и сортировки.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ