Why Django Rejected My Float Value: Understanding Python's Decimal Type
Today I ran into a small bug while building the Resume Management module for my Placement Portal.
The task seemed straightforward: convert a file size from bytes into kilobytes and store it in a Django DecimalField.
The calculation looked simple.
bytes / 1024
Then I rounded the result to two decimal places:
round(size / 1024, 2)
Everything appeared correct.
Printing the value showed something like:
10.47
But when I tried saving it to the database, Django rejected it.
The Confusing Part
At first, I couldn't understand why.
The value clearly had only two decimal places.
The database field also accepted two decimal places.
So why did it fail?
The answer lies in how Python represents floating-point numbers.
Although Python printed 10.47, the internal value wasn't necessarily exactly 10.47.
It could actually be something closer to:
10.469999999999998...
or
10.470000000000001...
Those hidden digits aren't visible when printing the value, but they still exist in memory.
When Django validates a DecimalField, those tiny floating-point inaccuracies can become significant.
The Solution
Instead of relying on floating-point arithmetic, I switched to Python's Decimal type.
The calculation now stays in decimal arithmetic from start to finish.
After dividing the value, I used quantize() to round it to exactly two decimal places.
This produces a true decimal value instead of a floating-point approximation.
Once I passed the Decimal object to the model, Django accepted it without any issues.
What I Learned
This bug reminded me of an important lesson.
Python's built-in data types are incredibly useful, but they're not always the right tool for every problem.
For everyday calculations, float works perfectly well.
However, whenever precision matters—such as:
- Currency
- Measurements
- File sizes stored in
DecimalField - Scientific calculations
Decimal is often the better choice.
It avoids the subtle precision problems that are inherent to floating-point arithmetic.
Final Thoughts
One thing I enjoy about building projects is that even the smallest features can teach something fundamental.
Today wasn't really about converting bytes into kilobytes.
It was about understanding the difference between how numbers look and how they're actually represented inside a computer.
That's a lesson I'll carry into every backend project I build.
I'm documenting every engineering lesson while building my Placement Portal in public.