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