Search code examples
jsondjangodecimalresponse

How do I enforce 2 decimal places on API response in Django?


I am making a small API server in Django. For one of my fields, I am using a decimal field which is responsible for representing $ dollar values, so I would like to have 2 decimal places at all times. But I'm struggling to have the exact format.

I'm using rest_framework and my base level response is encoded as a string with the following serializer is:

price = serializers.DecimalField(max_digits=10, decimal_places=2, required=True)

string representation

There is an option to turn off string coercion with "COERCE_DECIMAL_TO_STRING": False in settings.py, but then I face a problem that Decimal is not JSON serializable, and have to use FloatField where I cannot specify a format and end up with only 1 decimal place:

price = serializers.FloatField(required=True)

float representation

I searched for setting up FloatField format on the serializer but did not find any related option. I believe I also tried some other serializers like this one and did not achieve the goal, which is:

How do I enforce 2 decimal places on API response in Django?


Solution

  • Decimal is not supported by json, so formatting float is the only solution. You need to use a custom json encoder that specifies float format for json response and that formatted json is returned from the api.

    Your encoder can look something like this:

    # Encode Floats as "decimal" with two decimal places
    class DecimalEncoder(json.JSONEncoder):
    def encode(self, obj):
    
        if isinstance(obj, dict):
            result = '{'
            for key, value in obj.items():
                if isinstance(value, float):
                    encoded_value = format(value, '.2f')
                else:
                    encoded_value = json.JSONEncoder.encode(self, value)
    
                result += f'"{key}": {encoded_value}, '
    
            result = result[:-2] + '}'
            return result
        return json.JSONEncoder.encode(self, obj)
    

    Reference: https://www.geeksforgeeks.org/json-data-types/