【问题标题】:Swagger compatibility with custom fields on Django serializers?与 Django 序列化程序上的自定义字段的 Swagger 兼容性?
【发布时间】:2023-03-18 17:16:02
【问题描述】:

我最近被集成到使用 Django rest 框架和 swagger 的项目中。我不得不在某个时候为序列化程序定义一个自定义字段,它工作正常,但 swagger 无法识别它的类型(它总是将其标记为字符串)。

自定义字段:

class InheritableAttribute(serializers.ReadOnlyField):
    def __init__(self, attribute_name, serializer_class=None):
        super().__init__()
        self.attribute_name = attribute_name
        self.serializer_class = serializer_class

    def get_attribute(self, instance):
        value = getattr(instance, self.attribute_name)
        if not value:
            value = getattr(instance.product, self.attribute_name)
        return value

    def to_representation(self, value):
        if self.serializer_class:
            return self.serializer_class(value).to_representation(value)
        return super().to_representation(value)

序列化器(简化):

class Serializer:

    base_price = InheritableAttribute('base_price')
    keep_inventory_count = InheritableAttribute('keep_inventory_count')

大摇大摆:

swagger output

例如,我希望 base_price 为 float 而 keep_inventory_count 为 bool。

另外,您可能已经注意到自定义字段被重复用于不同类型的数据,因此类型应该以某种方式作为参数,但我可能可以弄清楚这些东西;我只需要知道如何设置自定义字段的类型,以便 swagger 正确显示它。

【问题讨论】:

  • 不,没有属性可以做到这一点,swagger使用序列化器或模型字段类型打开API字段类型映射以显示字段类型。

标签: django django-rest-framework swagger django-serializer


【解决方案1】:

不,没有属性可以做到这一点,swagger 使用序列化器或模型字段类型来打开 API 字段类型映射。但是,如果您想实现这一点,那么您可以使用以下方法,然后 swagger 可以根据您传递的字段类识别正确的字段类型。请参阅以下示例:

class InheritableAttribute:

    @staticmethod
    def create(attribute_name, serializer_field_class=None):
        serializer_field_class = serializers.ReadOnlyField if not serializers.ReadOnlyField else serializer_field_class

        class InstanceInheritableAttribute(serializer_field_class):
            def __init__(self, **kwargs):
                kwargs['read_only'] = True
                self.attribute_name = attribute_name
                super().__init__(**kwargs)

            def get_attribute(self, instance):
                value = getattr(instance, self.attribute_name)
                if not value:
                    value = getattr(instance.product, self.attribute_name)
                return value

            def to_representation(self, value):
                return super().to_representation(value)
        return InstanceInheritableAttribute()


class Serializer(serializers.Serializer):

    base_price = InheritableAttribute.create("base_price", serializers.FloatField)
    keep_inventory_count = InheritableAttribute.create("keep_inventory_count", serializers.BooleanField)

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多