AlxVallejo
AlxVallejo

Reputation: 3239

Django SerializerMethodField can't save a decimal

So, according to the docs, SerializerMethodField is a read-only field.

Well in my case, it's interfering with my write:

# old value is 2.5
data={'score': 1.7}
serializer = ScoreTraitSerializer(
        score_trait, data=data, partial=True)
    if serializer.is_valid():
        new_score_trait = serializer.save()

Now if I inspect the new_score_trait, my score is still 2.5.

The serializer looks as such:

score = serializers.SerializerMethodField()

def get_score(self, obj):
    if isinstance(obj.score, decimal.Decimal):
        return float(obj.score)
    else:
        return obj.score

If I comment out my SerializerMethodField, I can save the new decimal value (but can't serialize it).

So ... am I using my serializer correctly? Why does my write to the serializer hitting the SerializerMethodField?

Thanks in advance

Upvotes: 0

Views: 654

Answers (1)

Ykh
Ykh

Reputation: 7717

SerializerMethodField is a read-only field.Only used for to_representation, it's used for list/retrieve not create/update.

the serializer field score must conflict with model field score,try change it to:

float_score = serializers.SerializerMethodField(required=False)

def get_float_score (self, obj):
    if isinstance(obj.score, decimal.Decimal):
        return float(obj.score)
    else:
        return obj.score

See the source code you will know why:

class SerializerMethodField(Field):
    """
    A read-only field that get its representation from calling a method on the
    parent serializer class. The method called will be of the form
    "get_{field_name}", and should take a single argument, which is the
    object being serialized.

    For example:

    class ExampleSerializer(self):
        extra_info = SerializerMethodField()

        def get_extra_info(self, obj):
            return ...  # Calculate some data to return.
    """
    def __init__(self, method_name=None, **kwargs):
        self.method_name = method_name
        kwargs['source'] = '*'
        kwargs['read_only'] = True
        super(SerializerMethodField, self).__init__(**kwargs)

Upvotes: 1

Related Questions