Как создать индекс 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совместимы, см. их документацию .
Сама реализация, хотя и не очень элегантная, выглядит следующим образом: