如何使用多个DRF路由器创建多级API索引?
解决DRF多级API路由与Api Root层级展示问题
针对你需要的多级API结构和层级化Api Root需求,不需要合并DefaultRouter的registry,而是通过路由嵌套+自定义Api Root的方式实现,具体步骤如下:
1. 配置最内层子路由(bar/bar2/bar3/bar4的urls.py)
每个子模块的DefaultRouter仅负责自身资源,路径设为空字符串,前缀由上级路由传递:
# api/v1/foo/bar/urls.py from rest_framework.routers import DefaultRouter from .views import BarViewSet router = DefaultRouter() # 空字符串配合上级路由的/bar/,最终路径为/v1/foo/bar/... router.register(r'', BarViewSet, basename='bar') urlpatterns = router.urls
bar2/urls.py、bar3/urls.py、bar4/urls.py按此格式配置,替换对应ViewSet即可。
2. 配置中间层路由(foo/urls.py、foo2/urls.py)
用include嵌套下层路由,同时可添加自身的Api Root(可选):
# api/v1/foo/urls.py from django.urls import path, include from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.reverse import reverse # 可选:foo层级的Api Root @api_view(['GET']) def foo_api_root(request, format=None): return Response({ 'bar': reverse('bar-list', request=request, format=format), 'bar2': reverse('bar2-list', request=request, format=format) }) urlpatterns = [ path('', foo_api_root, name='foo-root'), # foo层级的根入口 path('bar/', include('api.v1.foo.bar.urls')), path('bar2/', include('api.v1.foo.bar2.urls')), ]
foo2/urls.py同理配置,添加foo2_api_root并嵌套bar3、bar4的路由。
3. 配置v1层级路由(v1/urls.py)
这里需要实现/v1/的Api Root,返回foo和foo2的链接,有两种方式:
方式一:自定义Api Root视图(推荐,灵活可控)
# api/v1/urls.py from django.urls import path, include from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.reverse import reverse @api_view(['GET']) def v1_api_root(request, format=None): return Response({ 'foo': reverse('foo-root', request=request, format=format), 'foo2': reverse('foo2-root', request=request, format=format) }) urlpatterns = [ path('', v1_api_root, name='v1-root'), path('foo/', include('api.v1.foo.urls', namespace='foo')), path('foo2/', include('api.v1.foo2.urls', namespace='foo2')), ]
方式二:用DefaultRouter的add_api_view快速实现
如果不需要foo/foo2自身的Api Root,可直接用此方式:
# api/v1/urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter router = DefaultRouter() # 为foo和foo2添加Api Root入口 router.add_api_view('foo', path('foo/', include('api.v1.foo.urls'))) router.add_api_view('foo2', path('foo2/', include('api.v1.foo2.urls'))) urlpatterns = router.urls
4. 最外层路由(api/urls.py)
只需包含v1的路由:
from django.urls import path, include urlpatterns = [ path('v1/', include('api.v1.urls')), ]
关键说明
router.registry.extend()会将其他路由的资源直接合并到当前Router,导致所有接口平级显示,不符合你的多级结构需求。通过include嵌套路由+自定义Api Root的方式,既能保证层级化的接口路径,又能生成符合预期的Api Root返回结果。
内容的提问来源于stack exchange,提问作者Gabriel Milan
相关产品推荐
相关产品推荐

