django drf-yasg不包含url的“API/”部分

8yparm6h  于 2023-05-30  发布在  Go
关注(0)|答案(1)|浏览(202)

我使用drf-yasg生成一个Swagger模式,但它删除了url的“API/”部分。

schema_view = get_schema_view(
openapi.Info(
    title="My API",
    default_version='v1',
    description="...",
    terms_of_service="https://www.google.com/policies/terms/",
    contact=openapi.Contact(email="hello@mycompany.com"),
    license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
router = routers.DefaultRouter()
router.register(r'spaces', SpacesViewSet, basename='spaces')

urlpatterns = [

url(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),

path('api/', include(router.urls)),
path('api/search-options', SearchPlacesOptionsView.as_view()),
]

result on /swagger

正如你所看到的,来自drf路由器的路由不包括url的/API部分。然而,对于常规的API/search-options端点,它也删除了/api部分,所以我不认为它与路由器有关。

ehxuflar

ehxuflar1#

我也有同样的问题,但没有人回答这个问题,所以我修复了它,我要与你分享我想这个问题的发生是因为他们在他们的包(drf_yasg)中有很多变化。
你应该覆盖OpenAPISchemaGenerator的get_paths()方法,并对其进行一些修改,
drf_yasg类中的原始OpenAPISchemaGenerator:

class OpenAPISchemaGenerator(object):
    # other methods ...
    def get_paths(self, endpoints, components, request, public):
    """Generate the Swagger Paths for the API from the given endpoints.

    :param dict endpoints: endpoints as returned by get_endpoints
    :param ReferenceResolver components: resolver/container for Swagger References
    :param Request request: the request made against the schema view; can be None
    :param bool public: if True, all endpoints are included regardless of access through `request`
    :returns: the :class:`.Paths` object and the longest common path prefix, as a 2-tuple
    :rtype: tuple[openapi.Paths,str]
    """
    if not endpoints:
        return openapi.Paths(paths={}), ''

    prefix = self.determine_path_prefix(list(endpoints.keys())) or ''
    assert '{' not in prefix, "base path cannot be templated in swagger 2.0"

    paths = OrderedDict()
    for path, (view_cls, methods) in sorted(endpoints.items()):
        operations = {}
        for method, view in methods:
            if not self.should_include_endpoint(path, method, view, public):
                continue

            operation = self.get_operation(view, path, prefix, method, components, request)
            if operation is not None:
                operations[method.lower()] = operation

        if operations:
            # since the common prefix is used as the API basePath, it must be stripped
            # from individual paths when writing them into the swagger document
            path_suffix = path[len(prefix):]
            if not path_suffix.startswith('/'):
                path_suffix = '/' + path_suffix
            paths[path_suffix] = self.get_path_item(path, view_cls, operations)

    return self.get_paths_object(paths), prefix

在我的应用程序中重写OpenAPISchemaGenerator CustomizedOpenAPISchemaGenerator类:

from collections import OrderedDict

from drf_yasg import openapi
from drf_yasg.generators import OpenAPISchemaGenerator

class CustomizedOpenAPISchemaGenerator(OpenAPISchemaGenerator):
    def get_paths(self, endpoints, components, request, public):
        if not endpoints:
            return openapi.Paths(paths={}), ''

        prefix = self.determine_path_prefix(list(endpoints.keys())) or ''
        assert '{' not in prefix, "base path cannot be templated in swagger 2.0"

        paths = OrderedDict()
        for path, (view_cls, methods) in sorted(endpoints.items()):
            operations = {}
            for method, view in methods:
                if not self.should_include_endpoint(path, method, view, public):
                    continue

                operation = self.get_operation(view, path, prefix, method, components, request)
                if operation is not None:
                    operations[method.lower()] = operation

            if operations:
                path_suffix = path[len(prefix):]
                if not path_suffix.startswith('/'):
                    path_suffix = '/' + path_suffix
                paths[path] = self.get_path_item(path, view_cls, operations)
                #  Only override this above line of upper level class paths[path_suffix] = ... to paths[path] = ...

        return self.get_paths_object(paths), prefix

我只替换这个:

paths[path_suffix] = self.get_path_item(path, view_cls, operations)

用这个:

paths[path] = self.get_path_item(path, view_cls, operations)

之后,你应该将这个新的生成器类路径到你的swagger配置,要做到这一点,你有两个选择:
1:使用django设置文件:

SWAGGER_SETTINGS = {
    'DEFAULT_GENERATOR_CLASS': 'path.to.CustomizedOpenAPISchemaGenerator',
}
  1. get_schema_view()函数中的path generator_class参数:
schema_view = get_schema_view(
    #     your other data
    generator_class=path.to.CustomizedOpenAPISchemaGenerator
)

相关问题