如何将一个APIRootView嵌套到另一个APIRootView中?
问题原因
- 原有写法存在两个核心问题:
- 直接将继承
nested.APIRootView的普通ViewSet注册到主路由器时,DRF的DefaultRouter不会自动将该入口添加到根API视图的返回列表中,因此根路径下看不到nested路由 - 嵌套的子路由器
nested的路由没有被实际挂载到/nested前缀下,即使手动访问/nested也无法正确加载只包含users的子根视图
- 直接将继承
- 不需要自定义ViewSet去继承APIRootView,直接利用DefaultRouter自带的根视图逻辑、搭配路由挂载即可实现需求。
实现代码
from rest_framework.routers import DefaultRouter from django.urls import include, path # 若使用Django 1.x/2.x旧版本,可替换导入:from django.conf.urls import url # 初始化主路由,注册snippets视图集 router = DefaultRouter() router.register(r"snippets", views.SnippetViewSet) # 初始化嵌套子路由,注册users视图集 nested_router = DefaultRouter() nested_router.register(r"users", views.UserViewSet) # 给主路由的根视图追加nested入口 original_root_view = router.get_api_root_view() def patched_root_view(request, *args, **kwargs): resp = original_root_view(request, *args, **kwargs) resp.data["nested"] = request.build_absolute_uri("nested/") return resp router.get_api_root_view = lambda: patched_root_view urlpatterns = [ path("", include(router.urls)), # 旧版本Django可替换为:url(r"^nested/", include(nested_router.urls)) # 将子路由挂载到nested前缀下,访问/nested/会自动显示子路由的根视图 path("nested/", include(nested_router.urls)), ]
实现效果
- 访问根路径
/时,API根列表会同时展示snippets和nested两个入口 - 访问
/nested/路径时,会加载子路由器自动生成的APIRootView,仅展示users路由 - 所有路由的跳转、枚举逻辑完全复用DRF DefaultRouter的原生实现,不需要额外维护冗余视图逻辑
内容的提问来源于stack exchange,提问作者Shridharshan
相关产品推荐
相关产品推荐

