Какое поле модели django лучше всего использовать для представления суммы в долларах США?

104

Мне нужно сохранить сумму в долларах США в поле модели Django. Какой тип поля модели лучше всего использовать? Мне нужно, чтобы пользователь вводил это значение (с проверкой ошибок, нужно только число с точностью до центов), форматировал его для вывода пользователям в разных местах и ​​использовал его для вычисления других чисел.

MikeN
источник

Ответы:

168

Поле десятичного является правильным выбором для стоимости валюты.

Это будет выглядеть примерно так:

credit = models.DecimalField(max_digits=6, decimal_places=2)
просто резкий
источник
104
Если вы не хотите представлять национальный долг, в этом случае max_digits должно быть> 20
Брон Дэвис
4
decimal_places = 2 не обязательно правильно, если вам это нужно для поддержки других валют. Некоторые валюты имеют три десятичных разряда, а биткойн - восьмерку
Ли Райан,
2
Я думаю, что этот пример верен почти для всех валют. Для представления валют в виде биткойнов, я думаю, гораздо лучше использовать целочисленное поле, чтобы сохранить сумму в сатоши, а затем показать ее конечному пользователю в том виде, в каком вы хотите (BTC, mBTC и т. Д.)
jion
Если вы не хотите представлять государственный долг Венесуэлы в национальной валюте Венесуэлы, в этом случае вам понадобится 21 max_digits
Луис Сейра
@LieRyan, это правда. Мы должны принять во внимание современные типы «валюты», чтобы предотвратить любые будущие модификации db. Без обид за использование цитат.
улучшение
35

Другие ответы на 100% верны, но не очень практичны, так как вам все равно придется вручную управлять выводом, форматированием и т. Д.

Я бы предложил использовать 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,
    )

Работает автоматически из шаблонов:

{{ somemodel.some_currency }}

Вывод:

$123.00

Он имеет мощный бэкэнд через python-money и, по сути, заменяет стандартные десятичные поля.

Майкл Томпсон
источник
(с проверкой ошибок, нужно только число с точностью до центов), отформатируйте его для вывода пользователям в разных местах и ​​используйте его для вычисления других чисел. В таких случаях использование DecimalFieldболее практично. И я считаю, что это применимо к большинству людей. Используя, django-moneyкак они выделены, включить обработку валюты . Так что это больше для проекта, включающего транзакции, такие как сайты электронной коммерции, платежный шлюз, цифровая валюта, банковское дело и т. Д.
Йео
Я бы сказал, что, поскольку они работают с долларом США - валютой, - имеет смысл использовать библиотеку обработки валюты, такую ​​как django-money (python-money), поскольку она заставляет все работать так, как вы ожидаете, и предоставляет будущие корректировки функций. В исходном вопросе говорится, что им нужно форматирование и расчет (как вы цитировали), и для этого вам лучше использовать библиотеку валют вместо простого десятичного поля.
Майкл Томпсон,
1
Что, если я хочу добавить два денежных поля или провести какие-то вычисления?
saran3h
1
@ saran3h вы можете работать с денежными экземплярами и выполнять вычисления, как с любым другим числовым (десятичным) экземпляром. Вы можете складывать / вычитать, умножать на целые числа и т. Д.
Майкл Томпсон,
9

Определите десятичную дробь и верните знак $ перед значением.

    price = models.DecimalField(max_digits=8, decimal_places=2)

    @property
    def price_display(self):
        return "$%s" % self.price
Чагатай Мелан
источник
6
Вы ведь понимаете, что только что создали бесконечный цикл рекурсии в своей собственности?
El Ninja Trepador,
Интересный. Могу я спросить, как это?
kingraphaii
2
field = models.DecimalField(max_digits=8, decimal_places=2)

Следует создать поле для PostgreSQL, например:

 "field" numeric(8, 2) NOT NULL

Это лучший способ для PostGreSQL хранить сумму в долларах США.

Если вам нужен тип поля PostgreSQL «двойная точность», то вам нужно сделать в модели django:

field = models.FloatField()
геройская шляпа
источник
3
Остерегайтесь представления денег в виде числа с плавающей запятой, так как люди, как правило, недовольны ошибками округления своих денег. См .: stackoverflow.com/questions/3730019/… для получения дополнительных сведений.
Адам Паркин,