markwalker_
markwalker_

Reputation: 12849

Django wont store .00 on whole number decimal fields

I'm trying to force Django to always store numbers with 2 decimal places but if the number is a whole one then it isn't store the .00

def clean_myfield(self):
    data = self.cleaned_data['myfield']
    self.cleandecimal(data)
    return data

def cleandecimal(self, data):
    data = Decimal(data).quantize(Decimal('.01'), rounding=ROUND_DOWN)
    print 'data ', data
    return data

My prints always display as intended e.g. 4.00 but that gets stored as 4

How can I override the save method to store the value without rounding it?

Upvotes: 0

Views: 1439

Answers (2)

miki725
miki725

Reputation: 27861

Its a representation issue. Decimal number stores numbers, not representations of them. Mathematically 1.00 is equal to 1. So its possible that your database backend stores smallest truncated decimal without all zeros - so it's probably not Django, but db. If you want to force Django to always return decimal with two decimal places, you can overwrite the DecimalField:

class MyDecimalField(models.DecimalField):
    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)
        places = kwargs.get('decimal_places', 2)
        self.q = Decimal(10) ** -places

    def to_python(self, value):
        value = super(self.__class__, self).to_python(value)

        if isinstance(value, Decimal):
            return value.quantize(self.q)

        else:
            return value

This will always return numbers with decimal_places as specified. You can use it the same way as you would normal DecimalField, like:

class FooModle(models.Model)
    number = MyDecimalField(decimal_places=2, max_digits=10)

Upvotes: 2

arulmr
arulmr

Reputation: 8836

Use models.DecimalField(max_digits = 6, decimal_places = 2) to store numbers with two decimal places.

Upvotes: 0

Related Questions