【问题标题】:How to use DRF Custom serializer field with DB model如何将 DRF 自定义序列化器字段与 DB 模型一起使用
【发布时间】:2019-09-13 09:18:36
【问题描述】:

我正在使用具有二进制字段的关系数据库,那么如何使用 DRF 序列化程序来保存字段值

我已经参考了文档https://www.django-rest-framework.org/api-guide/fields/#custom-fields 并理解了一些部分并在下面创建,但我不确定如何在序列化程序中使用它

型号

class MyData(models.Model):
    data = models.BinaryField()

自定义字段

class BinaryField(serializers.Field):
    def to_representation(self, value):
        return value.decode('utf-8')

    def to_internal_value(self, value):
         return value.encode('utf-8')

但是我应该如何在下面的序列化程序中使用它

class BlobDataSerializer (serializers.ModelSerializer):
    class Meta:
        model = MyData
        fields = ('id', 'data')

所以基本上我试图将传入的数据存储在二进制字段中。提前致谢

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    像这样:

    class BlobDataSerializer (serializers.ModelSerializer):
        class Meta:
            model = MyData
            fields = ('id', 'data')
    
        data = BinaryField()
    

    对于更可重用的解决方案,您还可以继承 ModelSerializer 并自定义 serializer_field_mapping

    https://www.django-rest-framework.org/api-guide/serializers/#customizing-field-mappings

    【讨论】:

    • 感谢您的回答,但如果我在序列化程序中添加新字段,我会看到这一点,然后它工作正常。但是如果模型中存在字段(例如数据)并且同样我必须应用 BinaryField ,它不起作用。那么如何申请现有的模型字段
    • 我不确定你的意思,你能发布一些代码以及哪里出错了吗?
    • 对不起,我的代码有问题。有效。谢谢。
    【解决方案2】:

    Serializer Method Field怎么样

    class BlobDataSerializer(serializers.ModelSerializer):
        data = serializers.SerializerMethodField()
    
        def get_data(self, obj):
            return obj.decode('utf-8')
    
        class Meta:
            model = MyData
            fields = ('id', 'data')
    

    【讨论】:

    • SerializerMethodFields 是只读的,所以如果你想能够编辑数据字段,你应该创建一个自定义字段。
    【解决方案3】:

    每个字段显式

    在序列化程序中,为每个自定义字段指定字段类型。

    class BlobDataSerializer (serializers.ModelSerializer):
        class Meta:
            model = MyData
            fields = ('id', 'data')
    
        data = BinaryField()
    

    对所有字段隐式

    对于更可重用的解决方案,您还可以继承 ModelSerializer 并自定义 serializer_field_mapping

    因为我们需要重写一个类变量(不是实例变量),所以它不像上面的解决方案那么简单,也有点“神奇”。

    class BlobDataSerializerMetaClass(type(serializers.ModelSerializer)):
        def __new__(cls, clsname, bases, attrs):
            # Call the __new__ method from the ModelSerializer metaclass
            super_new = super().__new__(cls, clsname, bases, attrs)
            # Modify class variable "serializer_field_mapping"
            # serializer_field_mapping: model field -> serializer field
            super_new.serializer_field_mapping[models.BinaryField] = BinaryField
            return super_new
    
    # Set the above metaclass as the serializer metaclass    
    class BlobDataSerializer (serializers.ModelSerializer, metaclass=BlobDataSerializerMetaClass):
        class Meta:
            model = MyData
            fields = ('id', 'data')
    

    https://www.django-rest-framework.org/api-guide/serializers/#customizing-field-mappings

    【讨论】:

    • 我无法编辑@Nico Griffioen 的答案,因为“编辑队列”已满,所以我发布了一个独立的答案。
    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 2021-03-19
    • 2017-02-04
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多