What is the best django model field to use to represent a US dollar amount?
Question:
I need to store a U.S. $
dollar amount in a field of a Django model. What is the best model field type to use? I need to be able to have the user enter this value (with error checking, only want a number accurate to cents), format it for output to users in different places, and use it to calculate other numbers.
Answers:
A decimal field is the right choice for the
currency value.
It will look something like:
credit = models.DecimalField(max_digits=6, decimal_places=2)
field = models.DecimalField(max_digits=8, decimal_places=2)
Note that max_digits should be >= decimal_places. This example setting would allow a value up to: 999,999.99
Docs: https://docs.djangoproject.com/en/1.10/ref/models/fields/#decimalfield
Define a decimal and return a $ sign in front of the value.
price = models.DecimalField(max_digits=8, decimal_places=2)
@property
def price_display(self):
return "$%s" % self.price
field = models.DecimalField(max_digits=8, decimal_places=2)
Should create a field for PostgreSQL like:
"field" numeric(8, 2) NOT NULL
Which is the best way for PostGreSQL stored US dollar amount.
If you need a PostgreSQL field type “double precision”, then you need do in django model:
field = models.FloatField()
The other answers are 100% right but aren’t very practical as you’ll still have to manually manage output, formatting etc.
I would suggest using django-money:
from djmoney.models.fields import MoneyField
from django.db import models
def SomeModel(models.Model):
some_currency = MoneyField(
decimal_places=2,
default=0,
default_currency='USD',
max_digits=11,
)
Works automatically from templates:
{{ somemodel.some_currency }}
Output:
$123.00
It has a powerful backend via python-money and it’s essentially a drop-in replacement for standard decimal fields.
You can use django-money for money
field:
First, install django-money[exchange]
as shown below:
pip install django-money[exchange]
*You can install django-money
without [exchange]
as shown below but it doesn’t have the functions to convert currencies so I recommend to install django-money[exchange]
as shown above:
pip install django-money
Next, add 'djmoney.contrib.exchange'
to INSTALLED_APPS
in settings.py
:
# "settings.py"
INSTALLED_APPS = [
...,
'djmoney.contrib.exchange',
]
Then, run the command below:
python manage.py migrate
Then, define a field with MoneyField()
, MinMoneyValidator()
, MaxMoneyValidator()
and Decimal as shown below:
# "models.py"
from djmoney.models.fields import MoneyField
from decimal import Decimal
from djmoney.models.validators import MaxMoneyValidator, MinMoneyValidator
class MyModel(models.Model):
money = MoneyField(
max_digits=5, decimal_places=2, default=0, default_currency='USD',
validators=[
MinMoneyValidator(Decimal(0.00)), MaxMoneyValidator(Decimal(999.99)),
]
)
Then, run the command below:
python manage.py makemigrations && python manage.py migrate
Then, you can add a value on Django Admin as shown below:
Then, you can get the value with $
and the value without $
using .amount
in Django View as shown below:
# "views.py"
from django.http import HttpResponse
from app.models import MyModel
def test(request):
print(MyModel.objects.all()[0].money) # Here
print(MyModel.objects.all()[0].money.amount) # Here
return HttpResponse("Test")
Then, these below are displayed on console:
$12.54
12.54
Next, you can convert 12.54 USD
to ... EUR
.
First, go to Open Exchange Rates, then sign up to get the exchange rates of currencies:
Then, copy App ID from your dashboard:
Then, set OPEN_EXCHANGE_RATES_APP_ID
with App ID in settings.py
:
# "settings.py"
# Here
OPEN_EXCHANGE_RATES_APP_ID = '368183b0b2644e999ef2a61bd38d0ca3'
Then, run the command below:
python manage.py update_rates
Then, you can convert 12.54 USD
to ... EUR
with convert_money()
and Money()
as shown below. *You have to use the value without $
using .amount
:
# "views.py"
from django.http import HttpResponse
from app.models import MyModel
from djmoney.contrib.exchange.models import convert_money
from djmoney.money import Money
def test(request):
money = MyModel.objects.all()[0].money.amount
print(convert_money(Money(money, 'USD'), 'EUR')) # Here
return HttpResponse("Test")
Then, 12.54 USD
is converted to 11.70 EUR
as shown below:
€11.70
You can see django-money doc which has more details.
I need to store a U.S. $
dollar amount in a field of a Django model. What is the best model field type to use? I need to be able to have the user enter this value (with error checking, only want a number accurate to cents), format it for output to users in different places, and use it to calculate other numbers.
A decimal field is the right choice for the
currency value.
It will look something like:
credit = models.DecimalField(max_digits=6, decimal_places=2)
field = models.DecimalField(max_digits=8, decimal_places=2)
Note that max_digits should be >= decimal_places. This example setting would allow a value up to: 999,999.99
Docs: https://docs.djangoproject.com/en/1.10/ref/models/fields/#decimalfield
Define a decimal and return a $ sign in front of the value.
price = models.DecimalField(max_digits=8, decimal_places=2)
@property
def price_display(self):
return "$%s" % self.price
field = models.DecimalField(max_digits=8, decimal_places=2)
Should create a field for PostgreSQL like:
"field" numeric(8, 2) NOT NULL
Which is the best way for PostGreSQL stored US dollar amount.
If you need a PostgreSQL field type “double precision”, then you need do in django model:
field = models.FloatField()
The other answers are 100% right but aren’t very practical as you’ll still have to manually manage output, formatting etc.
I would suggest using django-money:
from djmoney.models.fields import MoneyField
from django.db import models
def SomeModel(models.Model):
some_currency = MoneyField(
decimal_places=2,
default=0,
default_currency='USD',
max_digits=11,
)
Works automatically from templates:
{{ somemodel.some_currency }}
Output:
$123.00
It has a powerful backend via python-money and it’s essentially a drop-in replacement for standard decimal fields.
You can use django-money for money
field:
First, install django-money[exchange]
as shown below:
pip install django-money[exchange]
*You can install django-money
without [exchange]
as shown below but it doesn’t have the functions to convert currencies so I recommend to install django-money[exchange]
as shown above:
pip install django-money
Next, add 'djmoney.contrib.exchange'
to INSTALLED_APPS
in settings.py
:
# "settings.py"
INSTALLED_APPS = [
...,
'djmoney.contrib.exchange',
]
Then, run the command below:
python manage.py migrate
Then, define a field with MoneyField()
, MinMoneyValidator()
, MaxMoneyValidator()
and Decimal as shown below:
# "models.py"
from djmoney.models.fields import MoneyField
from decimal import Decimal
from djmoney.models.validators import MaxMoneyValidator, MinMoneyValidator
class MyModel(models.Model):
money = MoneyField(
max_digits=5, decimal_places=2, default=0, default_currency='USD',
validators=[
MinMoneyValidator(Decimal(0.00)), MaxMoneyValidator(Decimal(999.99)),
]
)
Then, run the command below:
python manage.py makemigrations && python manage.py migrate
Then, you can add a value on Django Admin as shown below:
Then, you can get the value with $
and the value without $
using .amount
in Django View as shown below:
# "views.py"
from django.http import HttpResponse
from app.models import MyModel
def test(request):
print(MyModel.objects.all()[0].money) # Here
print(MyModel.objects.all()[0].money.amount) # Here
return HttpResponse("Test")
Then, these below are displayed on console:
$12.54
12.54
Next, you can convert 12.54 USD
to ... EUR
.
First, go to Open Exchange Rates, then sign up to get the exchange rates of currencies:
Then, copy App ID from your dashboard:
Then, set OPEN_EXCHANGE_RATES_APP_ID
with App ID in settings.py
:
# "settings.py"
# Here
OPEN_EXCHANGE_RATES_APP_ID = '368183b0b2644e999ef2a61bd38d0ca3'
Then, run the command below:
python manage.py update_rates
Then, you can convert 12.54 USD
to ... EUR
with convert_money()
and Money()
as shown below. *You have to use the value without $
using .amount
:
# "views.py"
from django.http import HttpResponse
from app.models import MyModel
from djmoney.contrib.exchange.models import convert_money
from djmoney.money import Money
def test(request):
money = MyModel.objects.all()[0].money.amount
print(convert_money(Money(money, 'USD'), 'EUR')) # Here
return HttpResponse("Test")
Then, 12.54 USD
is converted to 11.70 EUR
as shown below:
€11.70
You can see django-money doc which has more details.