drf-yasg 提供了错误的 URI 路径

Sta*_*ute 6 django swagger django-rest-framework openapi drf-yasg

在我的应用程序中,我需要有多个 Swagger 页面,其中包含多个客户端的分组端点。

我的一个客户端(路径)提供移动应用程序 API,另一个提供 Web 客户端 API。URL 模式相应地保持在 2 种不同中urls.py

我正在使用drf-yasg为我的 API 生成模式。

为了生成swagger规范,我schema_views为每个urls.py文件分别初始化 2 个,如下所示:

from api_mobile.urls import urlpatterns as mobile_patterns
from api_web.urls import urlpatterns as web_patterns

mobile_schema_view = get_schema_view(
openapi.Info(
    title="Mobile API",
    default_version='v3',
),
public=True,
permission_classes=(permissions.AllowAny,),
patterns=mobile_patterns,
)

web_schema_view = get_schema_view(
    openapi.Info(
        title="Web API",
        default_version='v1',
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
    patterns=web_patterns,
)

urlpatterns = [
    path(
        'api/mobile/docs',
        mobile_schema_view.with_ui('swagger', cache_timeout=0),
        name='mobile-schema-ui'
    ),
    path(
        'api/web/docs',
        web_schema_view.with_ui('swagger', cache_timeout=0),
        name='web-schema-ui'
    ),

    path('api/mobile/v3/', include('api_mobile.urls'), name='mobile_urls'),
    path('api/web/v1/', include('api_web.urls'), name='web_urls'),
    ...
]
Run Code Online (Sandbox Code Playgroud)

Wheremobile_patternsweb_patterns只是一个 url 模式列表。

如果我打开http://localhost:8000/api/mobile/docshttp://localhost:8000/api/web/docs确实看到了两个模式列表正确生成的模式,但如果我尝试直接从swagger规范页面发出请求,所有端点都会返回404错误——它们都尝试向不存在的 url 模式发出请求而不提供完整路径到终点。

因此,如果我从mobile端点向任何视图发出请求,swagger 会尝试在

http://localhost:8000/some_mobile_url/ 代替 http://localhost:8000/api/mobile/v3/some_mobile_url/

另一个模式的情况是一样的,大摇大摆错误地请求http://localhost:8000/some_web_url/而不是使用完整路径 http://localhost:8000/api/web/v3/some_web_url/

显然,能够直接测试 APIswagger非常重要,因此在我的情况下,规范本身是不够的。

这是我错误配置swaggeritlesf的问题,还是我应该以某种方式提供路径,swagger以便相应地预先添加到每个 url 的完整路径?

Man*_*anu 4

这对我们来说效果很好:

api_schema.py

from django.conf.urls import include, url
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

from books.api.v1.urls import urlpatterns as api_v1


API_DESCRIPTION = openapi.Info(
    ...
)

schema_view = get_schema_view(
    info=...,
    ...
    url='https://oursite.company.io/',
    patterns=[
        url('api/v1/', include(api_v1)),
    ],
)
Run Code Online (Sandbox Code Playgroud)

books.api.v1.urls.py

from django.conf.urls import include, url

urlpatterns = [
    url(r'^books', ...),
    ...
]
Run Code Online (Sandbox Code Playgroud)

urls.py

from ...api_schema import schema_view

...
url(r'^api/v1/', include(api_v1)),
url(r'^api/schema(?P<format>\.json|\.yaml)$',
        schema_view.without_ui(cache_timeout=0),
        name='api_schema_v1'),
...
Run Code Online (Sandbox Code Playgroud)