我需要在 Django 模型的字段中存储美元金额。 使用的最佳模型字段类型是什么? 我需要能够让用户输入这个值(通过错误检查,只想要一个精确到美分的数字),将其格式化以输出给不同地方的用户,并用它来计算其他数字。
我建议使用
django-money:
credit = models.DecimalField(max_digits=6, decimal_places=2)
从模板自动工作:
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,
)
输出:
{{ somemodel.some_currency }}
它通过 python-money 拥有强大的后端,本质上是标准十进制字段的直接替代品。
field = models.DecimalField(max_digits=8, decimal_places=2)
money
,如下图:
django-money[exchange]
*您可以安装
pip install django-money[exchange]
而不安装
django-money
,如下所示,但它没有转换货币的功能,所以我建议安装[exchange]
,如上所示:django-money[exchange]
接下来,将
pip install django-money
添加到
'djmoney.contrib.exchange'
中的 INSTALLED_APPS
:core/settings.py
然后,运行以下命令:
# "core/settings.py"
INSTALLED_APPS = [
...,
'djmoney.contrib.exchange',
]
然后,在`my_app/models.py'中的
python manage.py migrate
模型中定义一个带有
MoneyField()
、MinMoneyValidator()
、MaxMoneyValidator()
和Decimal的字段,如下所示:MyModel
然后,运行以下命令:
# "my_app/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)),
]
)
然后,您可以在 Django Admin 上添加一个值,如下所示:
python manage.py makemigrations && python manage.py migrate
中的
$
来获取带 $
的值和不带 .amount
的值,如下所示:my_app/views.py
然后,控制台上会显示以下内容:
# "my_app/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")
接下来,您可以将
$12.54
12.54
转换为
12.54 USD
。首先,前往打开汇率App ID:
... EUR
中设置
OPEN_EXCHANGE_RATES_APP_ID
和App ID:core/settings.py
然后,运行以下命令:
# "core/settings.py"
# Here
OPEN_EXCHANGE_RATES_APP_ID = '368183b0b2644e999ef2a61bd38d0ca3'
然后,您可以使用
python manage.py update_rates
和
12.54 USD
将 ... EUR
转换为 convert_money()
,如下所示。 *您必须使用不带 Money()
的值,使用 $
:.amount
然后,
# "my_app/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")
转换为
12.54 USD
,如下所示:11.70 EUR
您可以查看django-money doc
€11.70
和core/tasks.py
中的
celerybeat代码每60分钟更新一次货币汇率,如下所示。 *
开放汇率在免费计划中每月可以接受 1000 个请求:
core/settings.py
*您应该将
# "core/tasks.py"
from celery import shared_task
from djmoney import settings
from django.utils.module_loading import import_string
@shared_task
def update_rates(app_id):
backend = import_string(settings.EXCHANGE_BACKEND)(
access_key=app_id
)
backend.update_rates()
print("Successfully updated")
并导入
OPEN_EXCHANGE_RATES_APP_ID
、app
和 crontab
放在 update_rates
中的 celery 节拍代码之前,如下所示:settings.py
应该为 PostgreSQL 创建一个字段,例如:
field = models.DecimalField(max_digits=8, decimal_places=2)
这是 PostGreSQL 存储美元金额的最佳方式。
如果您需要 PostgreSQL 字段类型“双精度”,那么您需要在 django 模型中执行以下操作:
"field" numeric(8, 2) NOT NULL
field = models.FloatField()
造成的问题多于它解决的问题,我很遗憾使用它来表示 Django 中的货币字段。
所以目前,我使用decimal.Decimal
来保存
cents的数量。只是在向用户显示时不要忘记除以 100。