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, використовуючи їх найкращі сторони.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ