多应用场景下Django ViewSet API的URL配置及API根路径展示问题
解决Django REST Framework多APP API路由整合问题
我来帮你搞定这个DRF路由配置的难题,让所有API都能在/api/根页面正常显示,同时保持各APP的路由独立性~
问题分析
你之前遇到的问题核心在于:每个APP单独使用DefaultRouter时,它会自动生成自己的根路由页面,当你在主urls.py中include多个这类路由文件时,只会显示第一个DefaultRouter生成的根页面;而主路由里的空DefaultRouter因为没有注册任何视图集,自然显示为空。
最优解决方案(保持APP路由独立)
我们可以让每个APP使用SimpleRouter(不会自动生成根页面),然后在主路由中用DefaultRouter合并所有APP的路由注册信息,这样既保持了各APP的路由独立性,又能在/api/根页面显示所有API链接。
步骤1:修改各APP的路由文件,改用SimpleRouter
accounts/urls.py
from . import views from rest_framework.routers import SimpleRouter # 替换成SimpleRouter router = SimpleRouter() router.register(r"accounts", views.AccountsViewSet, basename="accounts") urlpatterns = router.urls
pages/urls.py
from . import views from rest_framework.routers import SimpleRouter # 替换成SimpleRouter router = SimpleRouter() router.register(r"pages", views.PagesViewSet, basename="pages") urlpatterns = router.urls
步骤2:在主路由(core/urls.py)中合并所有APP的路由
from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter # 导入各APP的router实例 from accounts.urls import router as accounts_router from pages.urls import router as pages_router # 创建主router main_router = DefaultRouter() # 合并各APP的路由注册信息 main_router.registry.extend(accounts_router.registry) main_router.registry.extend(pages_router.registry) urlpatterns = [ path("admin/", admin.site.urls), path("api/", include(main_router.urls)), ]
这样配置后,访问http://localhost:8000/api/就能看到包含accounts和pages的API根页面了:
{ "accounts": "http://localhost:8000/api/accounts/", "pages": "http://localhost:8000/api/pages/" }
备选方案(小型项目适用)
如果你的项目规模较小,也可以直接在主路由中统一注册所有ViewSet,这种方式更简洁但会让主路由依赖各APP的视图:
from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter # 直接导入各APP的ViewSet from accounts.views import AccountsViewSet from pages.views import PagesViewSet router = DefaultRouter() router.register(r"accounts", AccountsViewSet, basename="accounts") router.register(r"pages", PagesViewSet, basename="pages") urlpatterns = [ path("admin/", admin.site.urls), path("api/", include(router.urls)), ]
为什么之前的配置失败?
- 你尝试
include("pages.urls", "accounts.urls")的方式错误:include()函数一次只能接受一个路由模块或元组参数,不能同时传多个。 - 单独
include(pages.urls)时,因为pages用了DefaultRouter,它生成的根页面会覆盖主路由的根页面,所以只显示pages的API。 - 主路由中的空
DefaultRouter没有注册任何ViewSet,所以根页面为空。
内容的提问来源于stack exchange,提问作者user8758206
相关产品推荐
相关产品推荐

