在Django Rest Framework中跨应用程序将自定义路由器扩展到默认路由器

Gje*_*t G 12 django django-rest-framework

我遇到了关于让API应用程序分离的问题,同时仍然能够使用可浏览的API进行导航.

我以前routers.py在我的主应用程序中使用了一个单独的文件,其中包含以下扩展名DefaultRouter.

class DefaultRouter(routers.DefaultRouter):
    def extend(self, router):
        self.registry.extend(router.registry)
Run Code Online (Sandbox Code Playgroud)

然后添加其他应用程序路由器,如下所示:

from . routers import DefaultRouter
from app1.urls import router as app1_router

# Default Router
mainAppRouter = DefaultRouter()
mainAppRouter.extend(app1_router)
Run Code Online (Sandbox Code Playgroud)

其中app1_router是一个新SimpleRouter对象.

现在问题发生在我想修改SimpleRouter并创建我自己的时候App1Router,比如这个

class App1Router(SimpleRouter):

    routes = [
        Route(
            url = r'^{prefix}{trailing_slash}$',
            mapping = {
                'get': 'retrieve',
                'post': 'create',
                'patch': 'partial_update',
            },
            name = '{basename}-user',
            initkwargs = {}
        ),
    ]
Run Code Online (Sandbox Code Playgroud)

这将无法正确处理我的扩展程序.作为一个例子,GETPATCH不会被识别为每当我延长了路由器允许的方法,但是当我不延长,但只能使用定制的路由器,一切工作正常.

我的问题是,如何在单独的应用程序中处理扩展自定义路由器,但仍然保持良好的可浏览API

Mac*_*ski 1

路由器注册表只是一个标准的Python列表,因此您可以直接在registy上调用 YourRouter.registry.extend(),而无需子类化DefaultRouter,请在此处检查DRF的来源。由于registry是一个列表,因此当您扩展registry时,您会在python列表顶部添加另一个python列表,这意味着调用YourRouter.registry.extend(app_router.registry)。对我有用的是从其他应用程序(SimpleRouters)导入路由器并将它们添加到默认路由器注册表的顶部。

#aplication_root/urls.py
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from app_3.urls import router as app_3_router


router = DefaultRouter()
router.registry.extend(app_3_router.registry)

urlpatterns = [

    path('api/', include(router.urls)),

]
Run Code Online (Sandbox Code Playgroud)

如果您尝试通过添加前缀来向应用程序添加版本控制,我建议您查看 DRF 中提供的版本控制架构 - 也许它可以满足您的需求 DRF 版本控制

例如,在您的设置中启用 URLPathVersioning

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning'
}
Run Code Online (Sandbox Code Playgroud)

上面截图的 urlparttern 列表看起来像这样

urlpatterns = [

    path('api/<version>/', include(router.urls)),
]
Run Code Online (Sandbox Code Playgroud)