如何在drf-yasg中设置路径参数的数据类型



我使用Django、DRF、DRF-yasg和Swagger Codegen自动构建TypeScript代码来访问我的REST API。

在Django后端,我添加了一个DRF:服务的路径

rest_router = routers.DefaultRouter()
rest_router.register(r'source/(?P<source_id>[0-9]+)/document', DocumentViewSet)

DocumentViewSet是DRF模型视图集。

正如您所看到的,source_id参数是数字类型的。但是,生成的API描述将source_id参数定义为类型String。

显然,路径设置中的数字regexp是不够的,所以我想我需要DocumentViewSet类中的一些类型注释?我尝试了以下代码,但没有效果:

@swagger_auto_schema(
manual_parameters=[
openapi.Parameter(name="source_id",
required=True,
type="integer",
in_="path",
description="Source reference",
),
],
)
class DocumentViewSet(viewsets.ModelViewSet):
serializer_class = rest_serializers.DocumentSerializer
queryset = models.Document.objects.all().order_by('id')

如何告诉drf yasg将source_id参数设置为Integer类型?

  1. drf-yasg上的标准OpenAPISchemaGenerator仅检查路径变量名称是否与视图查询集模型字段匹配,并使用模型字段的类型(如果存在(。否则默认为字符串。如果文档模型有一个名为";source_id";。对外关系也应该起作用,但在这种情况下,参数名称很可能是字段的名称(source(,而不是id引用(source_id(。

  2. @swagger_auto_schema应该应用于一个或多个视图方法,而不是视图类。AFAIK将其应用于视图类不会有任何作用。看见https://drf-yasg.readthedocs.io/en/stable/custom_spec.html#the-swagger自动模式装饰器

  3. 作为一个附带任务,我四处打听了一下,看看是否有可能使用蟒蛇内置的打字来确定类型,简短的答案是肯定的,但有点混乱。如果有人发现它有用,就扔掉它,使用它的风险自负。


class CustomSchemaGenerator(OpenAPISchemaGenerator):
def get_path_parameters(self, path, view_cls):
parameters = super().get_path_parameters(path, view_cls)
for p in parameters:
if p.in_ == openapi.IN_PATH and p.type == openapi.TYPE_STRING:
p.type = getattr(view_cls, f'path_type_{p.name}', openapi.TYPE_STRING)
return parameters

在上面的生成器中,我们允许drf-yasg进行初始类型确定,但随后添加了一个额外的步骤,允许在中重写类型视图类。

示例视图

class DocumentView(APIView):
path_type_source_id = openapi.TYPE_INTEGER

使用SWAGGER_SETTINGS 启用生成器

SWAGGER_SETTINGS = {
'DEFAULT_GENERATOR_CLASS': 'path.to.CustomSchemaGenerator',
}

在drf_yasf的新版本中,这可能会变得更容易,但我设法用类似于以下方式的方法使其工作:

from django.utils.decorators import method_decorator
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets

params = [
openapi.Parameter("source_id",
openapi.IN_PATH,
description="Source reference",
type=openapi.TYPE_INTEGER
)
]
@method_decorator(name="list", decorator=swagger_auto_schema(manual_parameters=params))
@method_decorator(name="create", decorator=swagger_auto_schema(manual_parameters=params))
@method_decorator(name="retrieve", decorator=swagger_auto_schema(manual_parameters=params))
@method_decorator(name="update", decorator=swagger_auto_schema(manual_parameters=params))
@method_decorator(name="partial_update", decorator=swagger_auto_schema(manual_parameters=params))
@method_decorator(name="destroy", decorator=swagger_auto_schema(manual_parameters=params))
class DocumentViewSet(viewsets.ModelViewSet):
serializer_class = rest_serializers.DocumentSerializer
queryset = models.Document.objects.all().order_by('id')

我在这里装饰了所有的基本ViewSet操作,但你可以只装饰你需要的操作,你也可以装饰你的自定义操作(在这种情况下不需要使用method_decorator:你可以直接用@swagger_auto_schema装饰操作(。请注意,如果要在类中重写基本操作,也可以直接使用@swagger_auto_schema来修饰它们。

最新更新