JavaRush /Курсы /Модуль 3: Django /Настройка маршрутизации для API

Настройка маршрутизации для API

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

Если посмотреть на работу веб-приложений в целом, маршрутизация определяет, какой обработчик будет вызван на конкретный запрос. Например, запрос GET /articles/1/ должен попасть на обработчик, который вернёт данные статьи с ID = 1. Вот где маршрутизация вступает в игру: она "прокладывает путь" между URL и вашим кодом.

В Django REST Framework маршрутизация берёт эти принципы и добавляет удобства: вы можете использовать как стандартные функции path() и re_path(), так и специальные маршрутизаторы (Routers), которые делают часть работы за нас. Разберёмся во всём по порядку.

Основы маршрутизации: связь URL с обработчиком

Начнём с базового подхода и будем использовать APIView. Например, предположим, что у нас есть простое приложение с моделью Article. Вот пример:

# models.py
from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

    def __str__(self):
        return self.title

Мы хотим создать API, чтобы получать список всех статей и добавлять новые. Для начала создадим два метода внутри представления APIView:

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer

class ArticleListCreateAPIView(APIView):
    def get(self, request):
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Теперь добавим маршруты для подключения к этим методам:

# urls.py
from django.urls import path
from .views import ArticleListCreateAPIView

urlpatterns = [
    path('articles/', ArticleListCreateAPIView.as_view(), name='article-list-create'),
]

Сейчас наши запросы попадут к ArticleListCreateAPIView, и всё заработает. Но при увеличении количества представлений (например, добавлении обработки GET /articles/<id>/) код маршрутизации станет громоздким. Чтобы решить эту проблему, мы можем использовать ViewSet.

Использование ViewSet для упрощения маршрутизации

Вместо того чтобы прописывать маршруты для каждого метода, DRF предлагает создать ViewSet, который объединяет логику для однотипных операций. Вот пример ViewSet для нашего API:

# views.py
from rest_framework.viewsets import ModelViewSet

class ArticleViewSet(ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

Обратите внимание, как лаконично объявлена эта структура: DRF сам знает, что ViewSet должен поддерживать GET, POST, PUT, DELETE и т.д.

Теперь идём к маршрутам. Вместо ручного прописывания используем маршрутизатор:

# urls.py
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet

router = DefaultRouter()
router.register(r'articles', ArticleViewSet, basename='article')

urlpatterns = router.urls

Благодаря этому мы получаем маршруты для всех CRUD-операций автоматически:

  • GET /articles/
  • POST /articles/
  • GET /articles/<id>/
  • PUT /articles/<id>/
  • DELETE /articles/<id>/

Нетрудно заметить, насколько это упрощает жизнь.

DefaultRouter и виды маршрутизаторов

  • DefaultRouter — это стандартный инструмент для автоматической генерации маршрутов. Он создаёт маршруты для списка, деталей и, что удобно, добавляет маршрут к корневому списку API. Это полезно для начальной настройки, но если у вас есть специфические требования, придётся всё-таки использовать кастомизации.

  • SimpleRouter. Если корневой список API не нужен, вы можете использовать SimpleRouter вместо DefaultRouter. Логика работы остаётся такой же, но он не добавляет "лишних" маршрутов.

  • Custom Router. Для уникальных требований можно вообще создать свой маршрутизатор. DRF позволяет переопределить его поведение путём наследования от BaseRouter. Но в рамках большинства проектов важно освоить базовые варианты.

Комбинирование маршрутов вручную и с помощью Router

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

# views.py
from rest_framework.decorators import action
from rest_framework.response import Response

class ArticleViewSet(ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    @action(detail=False, methods=['get'])
    def popular(self, request):
        popular_articles = Article.objects.filter(is_popular=True)
        serializer = self.get_serializer(popular_articles, many=True)
        return Response(serializer.data)

В urls.py это выглядит так:

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

router = DefaultRouter()
router.register(r'articles', ArticleViewSet, basename='article')

urlpatterns = [
    path('', include(router.urls)),
    path('articles/popular/', ArticleViewSet.as_view({'get': 'popular'})),
]

Теперь запрос GET /articles/popular/ вернёт популярные статьи.

Особенности и типичные ошибки

Когда работаешь с маршрутизацией, возникает ряд вопросов и потенциальный источник ошибок:

  1. Ошибка "NoReverseMatch". Если вы регистрируете маршруты через DefaultRouter, убедитесь, что указали корректный basename.
  2. Переопределение методов ViewSet. Если вам нужно определить кастомное поведение (например, разрешать удаление только админам), используйте методы ViewSet.
  3. Проблемы с включением маршрутизатора. Не забудьте про правильный импорт и подключение маршрутов с помощью include(router.urls).

Практическое задание

Теперь, когда вы знаете, как использовать маршруты и маршрутизаторы, создайте API для управления задачами в приложении todo. Модель задачи должна содержать поля:

  • title (название задачи),
  • description (описание),
  • is_done (статус выполнения).

Реализуйте API для:

  1. Списка задач,
  2. Добавления новой задачи,
  3. Редактирования задачи,
  4. Удаления задачи,
  5. Маршрут /tasks/completed/ для получения выполненных задач.

Убедитесь, что ваш API протестирован с помощью браузера или Postman.

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