使用drf-yasg,如何在Response中支持多个序列化器?

时间:2018-12-18 02:07:11

标签: django django-rest-framework swagger

有了我的drf的响应,其中仅包含单个序列化程序提供的数据,我们可以将其实现为:

screen -r

哪一个效果好极了,但有些请求要求构建字典,其中两个或三个键对应于不同的序列化器,例如

@swagger_auto_schema(
    operation_id='ID example',
    operation_description="Description example.",
    responses={status.HTTP_200_OK: Serializer4ModelA(many=True)},
)

我们如何在自动模式中描述它?我尝试了几种不同的方法,主要类似于以下方法:

response = {
    "a": serializer_data_for_model_a,
    "b": serializer_data_for_model_b,
    "c": serializer_data_for_model_c
}

但是在加载文档时总是失败,@swagger_auto_schema( operation_id='ID example', operation_description="Description example.", responses={status.HTTP_200_OK: openapi.Response( description='response description', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'a': Serializer4ModelA(many=True), 'b': Serializer4ModelB(many=True), 'c': Serializer4ModelC(many=True) }) )} ) 表示:

flex

我已经一遍又一遍地阅读了文档,并在github上搜索了一个示例,但是我找不到一个示例或任何这样做的人。所以我的问题是如何为包含返回的响应中的不同键的序列化程序不同的响应成功手动定义架构?

3 个答案:

答案 0 :(得分:0)

我最终能够做到这一点,虽然可能不是最优雅的解决方案,但它确实起作用。

我的drf具有自定义应用标签格式,因此我所有的应用都位于一个文件夹中,我们将此文件夹称为apps

对于我的问题,对于序列化程序,我们可以用自定义函数替换Serializer4ModelA的{​​{1}}的{​​{1}}部分中的properties

因此,我的想法是通过自动获取信息并自动构建openapi.Schema字典来基本上自己构建模式。这很hacky,但对我很有用,因为在我的文档中我还想传递Dynamodb的序列化器,因此我为Dynamodb序列化器做了一个非常相似的功能。

我只是做到了而已,它确实有效,但是显然需要更多地关注get_serializer(Serializer4ModelA())中的所有字段,从而更好地处理properties

但是,尽管如此,它是一种可行的解决方案,但不是通用的,必须根据您的特定项目进行调整和填充。

我大致实现了以下功能:

field mapping

答案 1 :(得分:0)

我通常要做的是创建另一个序列化程序(只是为了让drf-yasg可以生成文档)。

例如,如果我有一个返回的端点:

{
   "results": [..list of serialized results with serializer X...]
}

我创建第二个序列化器:

class Y(serializers.Serializer):
    results = X(many=True)

,然后在swagger_auto_schema装饰器中使用Y序列化器。

答案 2 :(得分:0)

我遇到了这个问题,正在寻找除了我最初的解决方案之外是否还有其他方法(与@Hernan 的解释相同),但没有找到。 drf_yasg.openapi.Schema (drf_yasg==1.20.0) 的代码表明它不接受任何序列化程序对象。所以正如@Hernan 已经说过的,解决这个问题的方法是有一个额外的序列化程序并在那里定义嵌套的子序列化程序。然后,将其直接或通过 swagger_auto_schema.responses(如下所示)传递给 openapi.Response.schema

from django.urls import path
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import serializers, status, views


class Serializer4ModelA(serializers.Serializer):
    dog = serializers.CharField(label="My dog is a good boy")
class Serializer4ModelB(serializers.Serializer):
    perro = serializers.CharField(label="Mi perro es un buen chico")
    hund = serializers.CharField(label="Mein Hund ist ein guter Junge")
    aso = serializers.CharField(label="Ang aso ko ay mabait na bata")
class Serializer4ModelC(serializers.Serializer):
    eey = serializers.CharField(label="Eygaygu waa wiil fiican")
class SampleResponseSerializer(serializers.Serializer):
    a = Serializer4ModelA(many=True)
    b = Serializer4ModelB(many=True)
    c = Serializer4ModelC(many=True)


class SampleView(views.APIView):
    @swagger_auto_schema(
        responses={
            status.HTTP_200_OK: openapi.Response(
                description="response description",
                schema=SampleResponseSerializer,
            )
        }
    )
    def get(self, request):
        pass

urlpatterns = [
    path("sample/", SampleView.as_view()),
]

输出: enter image description here