与 Django 序列化程序上的自定义字段的 Swagger 兼容性?

Posted

技术标签:

【中文标题】与 Django 序列化程序上的自定义字段的 Swagger 兼容性?【英文标题】:Swagger compatibility with custom fields on Django serializers? 【发布时间】:2021-06-19 09:27:14 【问题描述】:

我最近被集成到使用 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字段类型映射以显示字段类型。 【参考方案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)

【讨论】:

以上是关于与 Django 序列化程序上的自定义字段的 Swagger 兼容性?的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework 序列化程序中的自定义错误消息

从一个应用程序获取字段名称到 django 中的另一个应用程序

序列化程序django rest框架上的字段值属性错误

Django Rest框架:序列化程序上的共享字段

Django Rest Framework 中嵌套序列化程序的唯一验证

具有特定字段的自定义查询集的 Django ModelForm 实例