Reputation: 1554
My form contains a DecimalField
with the attributes max_digits=8, decimal_places=2, validators=[MinValueValidator(0)], blank=True, null=True
.
In my view, I receive the model returned by the form:
my_model = form.save(False)
# Do stuff with returned model
...
my_model.save()
When I come to access the value of the DecimalField
, price
, I get it without the trailing zeroes. Say the value entered in the form field was 50:
print(my_model.price)
# Prints 50
But when I get the model from scratch, then retrieve the price, I get it with the trailing zeroes.
my_model = MyModel.objects.get(id=my_model.id)
print(my_model.price)
# Prints 50.00
I am just wondering why this is the case.
Upvotes: 1
Views: 1394
Reputation: 477684
Well one of the problems with floating points is that they typically fail to represent a lot of decimal values. For example 0.3
can not be represented exactly.
On the other hand has Python a type called Decimal
that does not work with the IEEE-754 floating point specifications. But by formatting it as a stream of decimal digits. As a result it can represent decimal numbers correctly, and perform calculations correctly (but it will have a hard time storing numbers in a compact way).
Since databases typically use such representation as well, Django thus uses a Decimal
to prevent the loss of data when reading or writing to the database. This Decimal
contains the precision, and prints numbers like 50
with their precision (so 50.00
).
Django however aims to accept all kinds of numerical values, including int
s, float
s, etc. In that case the values are converted to a decimal representation when you write these to the database.
So in case you assign for example an int
to an attribute of a model instance, then that attribute will have type int
(well it is basically the way you assign an attribute to a Python object). If you then store it in the database, Django will serialize it as a decimal, and it is stored that way in the database. If you later fetch the model, you have a model in memory, with as attribute a Decimal
, that stores the number with the specified precision.
Upvotes: 2