Django-rest-framework: DecimalField: str value without trailing zeros

Created on 29 Aug 2018  路  6Comments  路  Source: encode/django-rest-framework

I guess, coerce_to_string=True in DecimalField should safely remove trailing zeros and coerce_to_string=False should leave value unchanged. If it's true - why my values are with trailing zeros?
In old version of DRF values were without trailing zeros as I remember

| vaue | 24.471635150166826 |

value = serializers.DecimalField(decimal_places=30, max_digits=35, default=0, coerce_to_string=True)
>> 24.471635150166826000000000000000

Most helpful comment

@carltongibson, have you had time to take a look at #6514?

All 6 comments

Just ran into this. I am using it to store SI multipliers for values series and having a series in kilo{something} it is not needed to output "1000.000000000000" in my JSON and its annoying to have to remember the amount of decimal places for simple tests.

This on the DecimalField seems to do it:

def quantize(self, value):
        """
        Quantize the decimal value to the configured precision.
        """
        if self.decimal_places is None:
            return value

        context = decimal.getcontext().copy()
        if self.max_digits is not None:
            context.prec = self.max_digits
        return value.quantize(
            decimal.Decimal('.1') ** self.decimal_places,
            rounding=self.rounding,
            context=context
        )

Maybe another option is to use .normalize() on the value?

decimal.Decimal('0.001000000).normalize()`
>> decimal.Decimal('0.001')

# but the following might be a problem for serializing but according to json standard for number it should be ok. (https://json.org/)

decimal.Decimal('1000.00000000).normalize()
>> decimal.Decimal('1E+3')
multiplier = fields.DecimalField(max_digits=25, decimal_places=12, normalize=True)

Another option could be to create a subclass of the field that makes the quantize function do nothing. but that would get problems if you got a result that has more decimal places than wanted and there would be no rounding.

Not sure what the best way to solve it would be.

@carltongibson added the rounding parameter on DecimalField. Maybe he could give some insight to what could be a good direction to solve the problem.

Seems to me like adding a normalize option would be good.

Another option could be to create a subclass...

This is always the first option. Capture the exact behaviour you need for your application. Then propose a change if you think it appropriate, with a set of test cases that show exactly the what behaviour is altered.

I suspect all the options here are a matter of choice. If we change the default behaviour someone else will complain. I'm not sure there's much we can do.

I assume this is related to changes in #4075 or #4339. Also, this sounds related to #6311, which has additional, extensive discussion. Not 100% sure, since I don't have the bandwidth to read all of these threads extensively.

in #6311 @tomchristie say that he would accept strip_trailing_zeros flag. Would a normalize argument achieving pretty much the same thing also be acceptable?

I think the normalize flag could be added without breaking any existing stuff. I'm working on a deadline right now but afterwards I could try and put together a PR for it.

Hey @Krolken. A PR is always worth looking at. 馃檪

@carltongibson, have you had time to take a look at #6514?

Was this page helpful?
0 / 5 - 0 ratings