Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Django DecimalField let me store Float or string?

I don't understand the behaviour of Django DecimalField.

It's defined as:

A fixed-precision decimal number, represented in Python by a Decimal instance.

However, with the following model:

class Article(models.Model)
    unit_price = DecimalField(max_digits=9, decimal_places=2)

I can create an article in at least 3 ways:

article = Article.objects.create(unit_price="2.3")
type(article.unit_price)
>>> str

article = Article.objects.create(unit_price=2.3)
type(article.unit_price)
>>> float

article = Article.objects.create(unit_price=Decimal('2.3'))
type(article.unit_price)
>>> decimal.Decimal

Why Django DecimalField is able to return something else than Decimal type?

What would be the best way to ensure my app never deals with floats for prices?

Thanks.

like image 898
David D. Avatar asked Dec 18 '22 01:12

David D.


1 Answers

Why Django DecimalField is able to return something else than Decimal type?

This is because Django is permissive during model creation and allows you to input any type to these fields without erroring out if what you input can be coerced to the specified type.

After inserting it in the database it gets the right type. You can verify this using refresh_from_db():

article = Article.objects.create(unit_price="2.3")
type(article.unit_price)
>>> str
article.refresh_from_db()
type(article.unit_price)
>>> decimal.Decimal

What would be the best way to ensure my app never deals with floats for prices?

The only way to ensure this is to coerce any price input to decimal.Decimal as soon as you know it's a price amount.

like image 77
dukebody Avatar answered Dec 20 '22 17:12

dukebody