簡體   English   中英

如何在drf-yasg中設置路徑參數的數據類型

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

我使用DjangoDRFdrf-yasgSwagger Codegen自動構建 TypeScript 代碼來訪問我的 REST API。

在 Django 后端,我添加了一個由 DRF 提供的路徑:

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

DocumentViewSet是 DRF ModelViewSet

可以看到, source_id參數是數值類型的。 但是,生成的 API 描述將source_id參數定義為 String 類型。

顯然路徑設置中的數字正則表達式是不夠的,所以我想我需要在DocumentViewSet class 中添加一些類型注釋? 我嘗試了以下代碼,但這沒有效果:

@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 僅檢查路徑變量名稱是否與視圖查詢集 model 字段匹配,如果存在則使用 model 字段的類型。 否則默認為字符串。 如果文檔 model 有一個名為“source_id”的數字字段,則您的原始代碼應該可以工作。 對外關系也應該起作用,但是在這種情況下,您的參數名稱很可能應該是字段的名稱(源)而不是 id 引用(source_id)。

  2. @swagger_auto_schema 應該應用於視圖方法,而不是視圖 class。 AFAIK 應用它來查看 class 什么都不做。 https://drf-yasg.readthedocs.io/en/stable/custom_spec.html#the-swagger-auto-schema-decorator

  3. 作為一個支線任務,我看了看是否可以使用 python 內置類型來確定類型,簡短的回答是肯定的,但有點混亂。 如果有人覺得它有用,就把它扔掉,使用它需要您自擔風險。


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 中覆蓋類型。

示例視圖

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 裝飾動作)。 請注意,如果您要在 class 中覆蓋它們,您也可以直接使用 @swagger_auto_schema 修飾基本操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM