djangoserializationdjango-rest-framework

Custom Django Rest Framework Serializer Field not running `to_representation()` if value is null


I would like a custom (read-only) serializer field that replaces the serialized value if it is None. I assumed that I could just overwrite to_representation(), but that doesn't seem to run. Here is some code:

models.py:

class Book(models.Model):
  title = models.CharField(max_length=255)
  rating = models.IntegerField(null=True)

serializers:

class ReplaceableSerializerField(serializers.ReadOnlyField):

  def to_representation(self, value):
    if value is None:
      return "this book sucks"
    return value

class BookSerializer(serializers.ModelSerializer):

  class Meta:
    model = Book
    fields = ("title", "rating",)

  rating = ReplaceableSerializerField(allow_null=True)

If I then do the following:

hamlet = Book(title="Hamlet")
BookSerializer(instance=hamlet).data

I get the following response:

{'title': 'Hamlet', 'rating', None}

Notice how the rating is None instead of "this book sucks".

Any idea on how to force to_representation() to run on null fields?


Solution

  • As far as I can understand from implementation, to_representation method does not get called if the value is None. So to avoid this problem, I think you can use SerializerMethodField. You can use it like this:

    class BookSerializer(serializers.ModelSerializer):
      rating = serailizer.SerializerMethodField()
    
      class Meta:
        model = Book
        fields = ("title", "rating",)
    
      def get_rating(self, obj):
          if obj.rating == None:
             return "Something"
          return obj.rating