JavaRush /Курсы /Модуль 3: Django /Использование DjangoFilterBackend

Использование DjangoFilterBackend

Модуль 3: Django
19 уровень , 5 лекция
Открыта

На прошлых занятиях мы погрузились в увлекательный мир создания API с использованием Django REST Framework (DRF). Мы узнали, что такое пагинация и почему она важна для нашей работы, освоили PageNumberPagination и LimitOffsetPagination, а также научились кастомизировать пагинацию под нужды нашего приложения.

Мы начали разбирать фильтрацию данных и как она позволяет эффективно обрабатывать большие объемы информации. Пришла пора раскрыть всю силу фильтрации и научиться использовать DjangoFilterBackend в наших представлениях API!

Что такое DjangoFilterBackend?

Фильтрация — это процесс выбора подмножества данных на основе заданных критериев. Django REST Framework поддерживает фильтрацию через стороннюю библиотеку django-filter, которая предоставляет мощный и гибкий способ фильтровать данные в ваших API.

DRF имеет встроенную поддержку фильтрации данных через DjangoFilterBackend, которая позволяет связывать параметры запроса и поиск данных через фильтры.

Официальная документация django-filter: https://django-filter.readthedocs.io/

Установка и настройка django-filter

Перед началом работы нам нужно установить библиотеку django-filter и добавить её в наш проект.

Установка

Запустите следующую команду для установки библиотеки:

pip install django-filter

После установки убедитесь, что библиотека добавлена в зависимости вашего проекта (requirements.txt), чтобы ваш коллега или вы через 6 месяцев не начали нервно искать её.

# requirements.txt
django-filter

Регистрация в настройках DRF

Нужно сообщить Django и DRF о том, что мы будем использовать DjangoFilterBackend. Для этого добавьте его в настройку DEFAULT_FILTER_BACKENDS в файле settings.py:

# settings.py

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',  # Подключаем DjangoFilterBackend
    ]
}

Теперь DRF знает, где искать логику фильтрации. Отлично, можно двигаться дальше!

Подключение фильтрации к представлениям API

Давайте подключим модель для экспериментов. Работать мы будем с моделью, отображающей каталог книг. Если её у вас нет, создайте её:

# models.py

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    genre = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    published_date = models.DateField()

    def __str__(self):
        return self.title

Не забудьте выполнить миграции для создания таблицы в базе данных:

python manage.py makemigrations
python manage.py migrate

Для отображения данных создадим сериализатор:

# serializers.py

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

Теперь добавим базовый ViewSet без фильтрации, чтобы видеть полный список наших книг:

# views.py

from rest_framework.viewsets import ReadOnlyModelViewSet
from .models import Book
from .serializers import BookSerializer

class BookViewSet(ReadOnlyModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

Настроим маршрутизацию:

# urls.py

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet, basename='book')

urlpatterns = [
    path('', include(router.urls)),
]

Протестируйте /books/, и вы увидите все доступные записи.

Настройка фильтрации

Теперь мы подключим DjangoFilterBackend и настроим базовую фильтрацию.

Добавим атрибут filterset_fields в наше представление:

# views.py

from django_filters.rest_framework import DjangoFilterBackend

class BookViewSet(ReadOnlyModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [DjangoFilterBackend]  # Включаем фильтрацию
    filterset_fields = ['author', 'genre', 'price']  # Указываем поля для фильтрации

Теперь мы можем фильтровать данные по переданным параметрам запроса. Например:

  • /books/?author=J.K.%20Rowling — вернёт все книги автора "J.K. Rowling".
  • /books/?genre=Fantasy&price=20.00 — вернёт фантастические книги стоимостью 20 долларов.

Кастомизация фильтров

Иногда требуется сложная логика фильтрации. Для этого мы можем создать собственный класс фильтрации.

Создайте файл filters.py в приложении, если его ещё нет:

# filters.py

import django_filters
from .models import Book

class BookFilter(django_filters.FilterSet):
    min_price = django_filters.NumberFilter(field_name='price', lookup_expr='gte')
    max_price = django_filters.NumberFilter(field_name='price', lookup_expr='lte')
    published_after = django_filters.DateFilter(field_name='published_date', lookup_expr='gte')

    class Meta:
        model = Book
        fields = ['author', 'genre', 'min_price', 'max_price', 'published_after']

Теперь подключим кастомный фильтр:

# views.py

from .filters import BookFilter

class BookViewSet(ReadOnlyModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = BookFilter  # Указываем кастомный фильтр

С таким фильтром ваш API получит дополнительную функциональность. Например:

  • /books/?min_price=10&max_price=30 — книги в диапазоне цен от 10 до 30.
  • /books/?published_after=2021-01-01 — книги, опубликованные после 2021 года.

Советы по фильтрации

  • Проверяйте производительность запросов. Фильтрация через базу данных работает быстрее, чем через Python, но сложные запросы могут замедлить API.
  • Документируйте параметры фильтрации. Укажите в документации API, какие параметры доступны и какие типы значений они принимают.
  • Используйте индексирование. Добавьте индексы к часто фильтруемым полям, чтобы повысить скорость запросов.

Теперь ваш API стал немного умнее и готов обрабатывать сложные запросы к данным. В следующей лекции мы разберём, как организовать поиск и сортировку данных в API, чтобы пользователи могли находить нужную информацию ещё быстрее и удобнее.

1
Задача
Модуль 3: Django, 19 уровень, 5 лекция
Недоступна
Добавление фильтрации через DjangoFilterBackend
Добавление фильтрации через DjangoFilterBackend
1
Задача
Модуль 3: Django, 19 уровень, 5 лекция
Недоступна
Добавление сложной фильтрации
Добавление сложной фильтрации
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ