3
votes

I'm using relation database which is having Binary Field, So how can I use DRF serializer to save the field value

I have referred the documentation https://www.django-rest-framework.org/api-guide/fields/#custom-fields and understood some of the part and created below, but I'm not sure how to use it in serializer

Model

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

Custom Field

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')

But how should I use this in my below serializer

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

So basically I'm trying to store incoming data in binary field. Thanks in advance

3

3 Answers

2
votes

Like this:

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

    data = BinaryField()

For a more reusable solution, you could also subclass ModelSerializer and customize the serializer_field_mapping.

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

0
votes

What about using 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')
0
votes

Explicitly per field

In the serializer, specify the field type for each custom field.

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

    data = BinaryField()

Implicitly for all fields

For a more reusable solution, you could also subclass ModelSerializer and customize the serializer_field_mapping.

Because we need to override a class variable (not an instance variable), it's not as straightforward as the above solution and it's also kind of "magical".

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')

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