Skip to content

Instantly share code, notes, and snippets.

@EnriqueSoria
Last active October 20, 2023 11:33
Show Gist options
  • Save EnriqueSoria/8203cd19d540ce22fd27e015433939bf to your computer and use it in GitHub Desktop.
Save EnriqueSoria/8203cd19d540ce22fd27e015433939bf to your computer and use it in GitHub Desktop.
Like SerializerMethodField, but formatting returned value with another serializer
from __future__ import annotations
from rest_framework import serializers
class FormattedSerializerMethodField(serializers.SerializerMethodField):
"""
Like SerializerMethodField, but allowing you to apply an optional
formatter serializer to the field's output.
"""
def __init__(self, formatter_serializer: serializers.Field | None = None, **kwargs):
self.formatter_serializer = formatter_serializer
super().__init__(**kwargs)
def to_representation(self, value):
unformatted_value = super().to_representation(value)
if not self.formatter_serializer:
return unformatted_value
return self.formatter_serializer.to_representation(unformatted_value)
if __name__ == "__main__":
from decimal import Decimal
import random
class TestSerializer(serializers.Serializer):
random_decimal = FormattedSerializerMethodField(
formatter_serializer=serializers.DecimalField(max_digits=3, decimal_places=1)
)
def get_random_decimal(self, instance) -> Decimal:
"""Returns a random decimal with two integer digits and three decimals"""
integer_part = random.randrange(10, 99)
decimal_part = random.randrange(100, 999)
return Decimal(f"{integer_part}.{decimal_part}")
serialized_data = TestSerializer(instance={}).data
# length is 4: two digits + 1 dot + 1 decimal
assert len(serialized_data["random_decimal"]) == 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment