Как создать индекс API с помощью нескольких маршрутизаторов DRF?

Я пытаюсь создать API с помощью DRF со следующей структурой (пример):

api/
├── v1/
│   ├── foo/
│   │   ├── bar/
│   │   │   └── urls.py # There's one `rest_framework.routers.DefaultRouter` here
│   │   ├── bar2/
│   │   │   └── urls.py # There's one `rest_framework.routers.DefaultRouter` here
│   │   ├── __init__.py
│   │   └── urls.py
│   ├── foo2/
│   │   ├── bar3/
│   │   │   └── urls.py # There's one `rest_framework.routers.DefaultRouter` here
│   │   ├── bar4/
│   │   │   └── urls.py # There's one `rest_framework.routers.DefaultRouter` here
│   │   ├── __init__.py
│   │   └── urls.py
│   ├── __init__.py
│   └── urls.py
├── __init__.py
└── urls.py

Интуитивно, моими конечными точками будут

https://api.example.com/v1/foo/bar/...
https://api.example.com/v1/foo/bar2/...
https://api.example.com/v1/foo2/bar3/...
https://api.example.com/v1/foo2/bar4/...

Но я хочу, чтобы эта Api Root веб-страница была доступна с уровня https://api.example.com/v1. Например, когда я запускаю curl https://api.example.com/v1, он показывает мне

{"foo":"https://api.example.com/v1/foo/","foo2":"https://api.example.com/v1/foo2/"}

и так далее.

С учетом этого, я полагаю, что способ сделать это - каким-то образом "объединить" эти DefaultRouters.

Я знаю, что я мог бы просто router.registry.extend(some_other_router.registry), но это заставило бы их все быть на одном уровне, а мне явно нужно, чтобы они были многоуровневыми, как показано выше.

В итоге я написал класс IndexRouter, который затем можно использовать следующим образом:

  • Пример 1: повторное использование ваших urlpatterns:
your_old_urlpatterns = []
router = IndexRouter(urlpatterns=your_old_urlpatterns)
urlpatterns = router.to_urlpatterns()
  • Пример 2: использование других маршрутизаторов DRF:
from my_app.urls import router as my_app_router

router = IndexRouter(routers={"my_app": my_app_router})

Вы также можете смешивать их. Кроме того, есть и другие полезные параметры, такие как:

  • name: установка имени страницы для навигации по хлебным крошкам
  • .
  • deprecated_func: функция, которая сообщает, является ли эта конечная точка устаревшей или нет (drf-yasg совместима)
  • swagger_operation_description: drf-yasg совместимы, см. их документацию
  • .
  • swagger_operation_summary: drf-yasg совместимы, см. их документацию
  • .

Сама реализация, хотя и не очень элегантная, выглядит следующим образом:

Вернуться на верх