代码之家  ›  专栏  ›  技术社区  ›  jupiar

使用drf yasg,如何支持响应中的多个序列化程序?

  •  0
  • jupiar  · 技术社区  · 7 年前

    通过我的DRF仅包含单个序列化程序提供的数据的响应,我们可以将其实现为:

    @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 说:

    "/usr/local/lib/python3.6/site-packages/flex/utils.py", line 125, in 
    get_type_for_value raise ValueError("Unable to identify type of 
    {0}".format(repr(value)))
    ValueError: Unable to identify type of 
    Serializer4ModelA(many=True):
    

    我一次又一次地阅读了这些文档,并搜索了Github以获取一个示例,但我找不到这样的示例或任何人。因此,我的问题是如何成功地为返回的响应中包含不同键的不同序列化程序的响应手动定义架构?

    1 回复  |  直到 7 年前
        1
  •  0
  •   jupiar    7 年前

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

    我的DRF有一个自定义的应用程序标签格式,所以我的所有应用程序都在一个文件夹中,我们称之为这个文件夹。 apps .

    在我的问题中,对于序列化程序,我们可以替换 Serializer4ModelA properties 剖面图 openapi.Schema 比如说,使用自定义函数 get_serializer(Serializer4ModelA()) .

    所以我的想法是通过自动获取信息和自动构建 性质 字典。它非常简单,但对我很有用,因为在我的文档中,我还想传递dynamodb的序列化程序,所以我为dynamodb序列化程序做了一个非常类似的函数。

    我只做了它,它工作,但显然需要更多的关注来覆盖 field mapping ,更好地处理 SerializerMethodFields .

    但同样重要的是,这是一个有效但非通用的解决方案,根据您的特定项目,必须进行调整和改进。

    我大致实现了以下功能:

    from drf_yasg import openapi
    from drf_yasg.inspectors import SwaggerAutoSchema
    from drf_yasg.utils import swagger_auto_schema
    from drf_yasg.inspectors import FieldInspector
    from drf_yasg.utils import swagger_serializer_method
    import rest_framework
    
    rest_framework_openapi_field_mapping = {
         "ListField": openapi.TYPE_ARRAY,
         "CharField": openapi.TYPE_STRING,
         "BooleanField": openapi.TYPE_BOOLEAN,
         "FloatField": openapi.TYPE_NUMBER,
         "DateTimeField": openapi.TYPE_STRING,
         "IntegerField": openapi.TYPE_INTEGER,
         "SerializerMethodField": openapi.TYPE_STRING
    }
    
    def parse_rest_framework_field(field):
        rest_framework_field_type = field.split("(")[0]
        openapi_field_type = 
        rest_framework_openapi_field_mapping[rest_framework_field_type]
        if "help_text=" in field:
            field_description = field.split("help_text='")[-1].split("'")[0]
        else:
            field_description = None
        return openapi.Schema(type=openapi_field_type, description=field_description)
    
    def parse_serializer(serializer):
        properties = {}
        for k,v in serializer.get_fields().items():
            if v.__module__ == "rest_framework.fields":
                properties[k] = parse_rest_framework_field(str(v))
            elif v.__module__.startswith("apps."):
                serializer = str(v).strip().split("(")[0]
                exec(f"from {v.__module__} import {serializer}")
                eval_serializer = eval(f"{serializer}()")
                properties[k] = openapi.Schema(type=openapi.TYPE_OBJECT, properties=parse_serializer(eval_serializer))
            else:
                pass
        return properties
    
    def get_serializer(serializer, description):
        """ Needs to return openapi.Schema() """
        properties = parse_serializer(serializer)
        return_openapi_schema = openapi.Schema( type=openapi.TYPE_OBJECT, properties=properties, description=description)
        return return_openapi_schema
    
    推荐文章