JavaRush /Курсы /Модуль 3: Django /SimpleRouter и DefaultRouter

SimpleRouter и DefaultRouter

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

Давайте договоримся: мы не будем писать избыточный boilerplate-код, если задачу можно автоматизировать. Django REST Framework предлагает нам прекрасный инструмент — Routers, которые облегчают настройку маршрутов для API. Сегодня мы познакомимся с двумя популярными реализациями Routers: SimpleRouter и DefaultRouter.

Что такое Router?

Router — это объект в Django REST Framework, который автоматически связывает ваш ViewSet с маршрутами URL. Например, если у нас есть модель Product и соответствующий ViewSet для неё, то Router может создать маршруты для работы с этим ресурсом (например, /products/ для списка продуктов и /products/<id>/ для работы с конкретным продуктом).

Чтобы вручную настроить маршруты для каждого ресурса в API нужно написать очень много кода. Это минимум четыре маршрута для CRUD-операций (Create, Retrieve, Update, Delete) плюс, возможно, маршруты для дополнительных кастомных действий. Routers избавляют вас от этой рутины — они автоматически создают маршруты для каждого метода вашего ViewSet.

Routers сканируют ваш ViewSet и определяют, какие стандартные маршруты (например, list, retrieve, create, update, destroy) должны быть созданы. Затем они генерируют соответствующие URL и добавляют их в маршруты вашего проекта.

SimpleRouter и DefaultRouter: в чём разница?

Итак, Django REST Framework предлагает несколько готовых реализаций Routers. Наиболее популярные из них — это SimpleRouter и DefaultRouter.

SimpleRouter, как следует из названия, — это базовая реализация Router. Он создаёт маршруты для стандартных методов ViewSet (CRUD), но не добавляет ничего лишнего. Если вы хотите, чтобы ваш API был минималистичным и не имел лишнего функционала, SimpleRouter — ваш выбор.

Пример использования SimpleRouter

Давайте посмотрим, как использовать SimpleRouter для настройки маршрутов.

from rest_framework.routers import SimpleRouter
from django.urls import path, include
from myapp.views import ProductViewSet

# Создаём SimpleRouter
router = SimpleRouter()

# Регистрируем ViewSet
router.register(r'products', ProductViewSet, basename='product')

# Подключаем маршруты
urlpatterns = [
    path('', include(router.urls)),
]

Если вы зарегистрировали ProductViewSet с SimpleRouter, он создаст следующие маршруты:

Маршрут Метод HTTP Описание
/products/ GET Список продуктов
/products/ POST Создание нового продукта
/products/<id>/ GET Получение отдельного продукта
/products/<id>/ PUT Полное обновление продукта
/products/<id>/ PATCH Частичное обновление продукта
/products/<id>/ DELETE Удаление продукта

Как видно, этот Router создаёт только базовые маршруты.

DefaultRouter и пример его использования

DefaultRouter является более мощной версией Router и включает дополнительные возможности. Помимо стандартных маршрутов, он автоматически генерирует URL для корневого представления API (API root). Это представление можно использовать, чтобы увидеть список всех доступных ресурсов API. DefaultRouter идеально подходит для создания более информативных API.

Использование DefaultRouter почти идентично SimpleRouter. Разница лишь в том, что DefaultRouter добавляет корневое представление.

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

# Создаём DefaultRouter
router = DefaultRouter()

# Регистрируем ViewSet
router.register(r'products', ProductViewSet, basename='product')

# Подключаем маршруты
urlpatterns = [
    path('', include(router.urls)),
]

DefaultRouter добавляет все те же маршруты, что и SimpleRouter, но также добавляет корневой маршрут:

Маршрут Метод HTTP Описание
/ GET Корневое представление API
/products/ GET Список продуктов
/products/ POST Создание нового продукта
/products/<id>/ GET Получение отдельного продукта
/products/<id>/ PUT Полное обновление продукта
/products/<id>/ PATCH Частичное обновление продукта
/products/<id>/ DELETE Удаление продукта

Если вы перейдёте на корневой маршрут /, DefaultRouter предоставит вам JSON со списком всех зарегистрированных ViewSet. Это удобно для документации и тестирования API.

Таблица сравнения SimpleRouter и DefaultRouter

Характеристика SimpleRouter DefaultRouter
Генерация базовых маршрутов
Поддержка API root
Простота использования

Когда использовать SimpleRouter, а когда DefaultRouter?

Все зависит от ваших потребностей:

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

Пример проекта с SimpleRouter и DefaultRouter

Давайте рассмотрим пример приложения, в котором используются оба Router.

Модели

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=10, decimal_places=2)

Сериализаторы

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

ViewSet

from rest_framework.viewsets import ModelViewSet
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

Настройка маршрутов


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

# Создаём SimpleRouter
simple_router = SimpleRouter()
simple_router.register(r'simple-products', ProductViewSet, basename='simple-product')

# Создаём DefaultRouter
default_router = DefaultRouter()
default_router.register(r'products', ProductViewSet, basename='product')

# Подключаем оба Router
urlpatterns = [
    path('simple/', include(simple_router.urls)),
    path('default/', include(default_router.urls)),
]

Теперь у нас есть два разных маршрута:

  1. /simple/simple-products/ — минималистичный маршрут с использованием SimpleRouter.
  2. /default/products/ — маршрут с корневым представлением через DefaultRouter.

Попробуйте открыть /default/ в браузере, и вы увидите корневое представление API.

Типичные ошибки при использовании Routers

Часто новички сталкиваются с несколькими проблемами:

  1. Отсутствие basename. Если ваш ViewSet не имеет атрибута queryset, вы обязаны указать basename при регистрации в Router. Иначе вы получите ошибку.

    router.register(r'products', ProductViewSet)  # Ошибка
    router.register(r'products', ProductViewSet, basename='product')  # Правильно
    
  2. Дублирование маршрутов. Убедитесь, что разные Routers (например, SimpleRouter и DefaultRouter) не генерируют одинаковые маршруты, иначе вы вызовете конфликт.

  3. Пропуск include(router.urls). Если забыть подключить маршруты Router в urlpatterns, API просто не будет работать. Всегда проверяйте, что include используется правильно.

И на заметку: DefaultRouter автоматически добавляет / к корневому маршруту. Если вы не хотите этого, используйте SimpleRouter.

На этом всё! Теперь, когда вы научились использовать SimpleRouter и DefaultRouter, можете создавать более удобные и оптимальные маршруты для ваших ViewSet, используя их лучшие стороны.

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