简体   繁体   English

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

[英]How to set data type of path parameter in drf-yasg

I use Django , the DRF , drf-yasg and Swagger Codegen to automatically build TypeScript code to access my REST API.我使用DjangoDRFdrf-yasgSwagger Codegen自动构建 TypeScript 代码来访问我的 REST API。

In the Django backend I added a path to be served with the DRF:在 Django 后端,我添加了一个由 DRF 提供的路径:

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

DocumentViewSet is a DRF ModelViewSet . DocumentViewSet是 DRF ModelViewSet

As you can see, the source_id parameter is of numeric type.可以看到, source_id参数是数值类型的。 However, the resulting generated API description defines the source_id parameter as type String.但是,生成的 API 描述将source_id参数定义为 String 类型。

Obviously the numeric regexp in the path setting is not enough so I guess I need some type annotation in the DocumentViewSet class?显然路径设置中的数字正则表达式是不够的,所以我想我需要在DocumentViewSet class 中添加一些类型注释? I tried the following code, but this showed no effect:我尝试了以下代码,但这没有效果:

@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')

How can I tell drf-yasg to set the source_id parameter to type Integer?我如何告诉 drf-yasg 将source_id参数设置为键入 Integer?

  1. The standard OpenAPISchemaGenerator on drf-yasg only checks if the path variable name matches with the view queryset model field, and uses the type of the model field if such exists. drf-yasg 上的标准 OpenAPISchemaGenerator 仅检查路径变量名称是否与视图查询集 model 字段匹配,如果存在则使用 model 字段的类型。 Otherwise it defaults to string.否则默认为字符串。 Your original code should work if the Document model has a numeric field named "source_id".如果文档 model 有一个名为“source_id”的数字字段,则您的原始代码应该可以工作。 Foreign relations should work as well, but it's very much possible that in that case your parameter name should be the name of the field (source) and not the id reference (source_id).对外关系也应该起作用,但是在这种情况下,您的参数名称很可能应该是字段的名称(源)而不是 id 引用(source_id)。

  2. @swagger_auto_schema should be applied on the view method or methods, not the view class. @swagger_auto_schema 应该应用于视图方法,而不是视图 class。 AFAIK applying it to view class does nothing. AFAIK 应用它来查看 class 什么都不做。 See https://drf-yasg.readthedocs.io/en/stable/custom_spec.html#the-swagger-auto-schema-decoratorhttps://drf-yasg.readthedocs.io/en/stable/custom_spec.html#the-swagger-auto-schema-decorator

  3. As a side quest I poked around a bit to see if it's possible to determine the type using pythons built-in typing, and the short answer is yes, but it's a bit messy.作为一个支线任务,我看了看是否可以使用 python 内置类型来确定类型,简短的回答是肯定的,但有点混乱。 Throwing this out in case anyone finds it useful, use it with your own risk.如果有人觉得它有用,就把它扔掉,使用它需要您自担风险。


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

In the above generator, we allow drf-yasg to do the initial type determination, but then add an extra step that allows overriding type in the view class.在上面的生成器中,我们允许 drf-yasg 进行初始类型确定,然后添加一个额外的步骤,允许在视图 class 中覆盖类型。

Example view示例视图

class DocumentView(APIView):
    path_type_source_id = openapi.TYPE_INTEGER

Enable the generator with SWAGGER_SETTINGS使用 SWAGGER_SETTINGS 启用生成器

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

This may be something made easier in a newer version of drf_yasf, but I managed to get it working with something similar to the following way:在较新版本的 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')

I have here decorated all base ViewSet actions but you could decorate only the ones you need, you can also decorate your custom actions (no need to use method_decorator in that case: you can directly decorate the action with @swagger_auto_schema).我在这里装饰了所有基本的 ViewSet 动作,但你可以只装饰你需要的那些,你也可以装饰你的自定义动作(在这种情况下不需要使用 method_decorator:你可以直接用 @swagger_auto_schema 装饰动作)。 Note that you could also decorate the base actions with @swagger_auto_schema directly if you were to override them in your class.请注意,如果您要在 class 中覆盖它们,您也可以直接使用 @swagger_auto_schema 修饰基本操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM