1

I have few places in database when I'm using DecimalField. Unfortunalety I have to handle both double and float data as input - and there is my problem.

I want to do brutal cut off the value (after second decimal place), not a math round. I store calculated value which goal is to be exceeded hardly (if I have value 49.9832100000032131 it is still less than 50, so I won't round it up). But as i said - I want to save it as 48.98 in database (with 2 decimal places) - saving memory and enough representation.

My first solution is using custom django field, something like this:

class DecimalFixedField(models.DecimalField):

def __init__(self, *args, **kwargs):
    kwargs['value'] = "{0:.2f}".format( kwargs['value'] )            
    # or ? self.value = "{0:.2f}".format( kwargs['value'] )
    super(DecimalFixedField, self).__init__(*args, **kwargs)

Of course I should hardcode decimal_places = 2 in kwargs or use it in code not value 2, but... what about rest? Do you have hint, better idea?

What is important - I don't wanna write "{0:.2f}".format(...) in many places in code! I wanted to do it in OOP methodology, because I'm using DecimalField in many models... and making this pre-processing looks as nice solution. Any thoughts how it shoud be implemented properly?

Izzy
  • 755
  • 2
  • 9
  • 17

2 Answers2

1

After thinking and trying I did something like this:

class DecimalFixedField(models.DecimalField):

    def pre_save(self, model_instance, add):

        # reading value
        value_field = getattr(model_instance, self.attname)

        # casting to decimal if the value is not a decimal (float for example)
        if not isinstance(value_field, decimal.Decimal):
            value_field = decimal.Decimal(str(value_field))

        # there you can cut off the value
        quantized_value = value_field.quantize(decimal.Decimal(str(0.1**self.decimal_places)), rounding=decimal.ROUND_DOWN)

        # saving value
        setattr(model_instance, self.attname, quantized_value)
        return quantized_value

mayby it will be helpful for someone :)

Izzy
  • 755
  • 2
  • 9
  • 17
0

try to use this:

from decimal import Decimal

my_value = Decimal(value) 
Roberth Solís
  • 1,520
  • 18
  • 16
  • I know this but as I said - I have 8 models using DecimalField and... I wanted do do it in elegant way - in one place. Not in every new model or every place in code where float value can be saved into DecimalField :) – Izzy Apr 19 '16 at 16:16
  • While this code may answer the question, providing additional context regarding why and/or how it answers the question would significantly improve its long-term value. Please [edit] your answer to add some explanation. – CodeMouse92 Apr 19 '16 at 19:02