Django-rest-framework: 如何在 SerializerMethodField 上设置字段类型以生成 OpenAPI 模式?

创建于 2020-01-13  ·  3评论  ·  资料来源: encode/django-rest-framework

考虑这个无用的序列化器:

class MySerializer(serializers.Serializer):

    random_number = serializers.SerializerMethodField()

    def get_random_number(self):
        # Chosen by fair dice roll.
        # Guaranteed to be random.
        return 4

假设您在端点中添加了这个序列化程序并生成了 OpenAPI 模式,序列化程序将如下所示:

properties:
  random_number:
    type: string
  required:
  - random_number

这里的问题是没有办法告诉 DRF 在这里使用type: number 。 我想到了几种可能:

  • output_field属性,如serializers.SerializerMethodField(output_field=serializers.IntegerField()) ,类似于 Django 的查询表达式
  • 一个装饰器,比如openapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
  • 一个属性,类似于设置管理操作的描述:

    random_number = serializers.SerializerMethodField()
    
    def get_random_number(self):
      return 4
    
    get_random_number.output_field = serializers.IntegerField()
    
  • 只是 DRF 不支持的东西,可能应该在某处记录下来作为可能的警告。
Enhancement Schema Generation

最有用的评论

对我来说,我认为我更喜欢的 API 是使用类型提示的东西,例如:

def get_foo(self, obj) -> int:
    return 1

它适用于当前支持的每个 Python 版本。 这个想法在https://github.com/encode/django-rest-framework/pull/7089中使用过,但它没有被分离到另一个 PR 中。 看看那个实现,它似乎不处理集合。 在某些时候,您最好使用嵌套序列化程序,但我认为应该支持像List[int]List[str]Dict[str, int]等简单的情况。

@carlfarrington你怎么看? 这种方法值得尝试还是有问题? 如果值得尝试,是否也值得获得一些基本的东西,它可以处理基本类型并暂时忽略嵌套字段,还是我们从一开始就想要(嵌套或不嵌套)数组和对象?

所有3条评论

嗨@Lucidiot。

我想立即执行此操作的方法是覆盖AutoSchema._map_field()

您可以按序列化程序/视图执行该操作以期望相关字段,也可以像您说的那样添加属性。

我们最终会以这种方式解决问题,但目前我不确定 API 方面的最佳选择。

对我来说,我认为我更喜欢的 API 是使用类型提示的东西,例如:

def get_foo(self, obj) -> int:
    return 1

它适用于当前支持的每个 Python 版本。 这个想法在https://github.com/encode/django-rest-framework/pull/7089中使用过,但它没有被分离到另一个 PR 中。 看看那个实现,它似乎不处理集合。 在某些时候,您最好使用嵌套序列化程序,但我认为应该支持像List[int]List[str]Dict[str, int]等简单的情况。

@carlfarrington你怎么看? 这种方法值得尝试还是有问题? 如果值得尝试,是否也值得获得一些基本的东西,它可以处理基本类型并暂时忽略嵌套字段,还是我们从一开始就想要(嵌套或不嵌套)数组和对象?

我们将为 3.12 宣传和记录map_field() 。 这是去这里的正确方式。

此页面是否有帮助?
0 / 5 - 0 等级