ChatGPT解决这个技术问题 Extra ChatGPT

What is the best django model field to use to represent a US dollar amount?

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.


u
user8193706

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)

Unless you want to represent the national debt, in which case max_digits has to be > 20
decimal_places=2 is not necessarily correct if you need this to support other currencies. Some currencies have three decimal places, and Bitcoin has a whooping 8.
I think this example is correct almost to all currencies. To represent currencies as Bitcoin, I think is much better to use an integer field to save the amount in satoshis, and then show it to the final user in the representation that you want (BTC, mBTC, etc)
@LieRyan that's true. We have to take note of modern types of "currency" to prevent any future db modifications. No offence for the use of quotes.
This answer stackoverflow.com/questions/224462/… suggests using max_digits=19, decimal_place=4 to be safe.
M
Michael Thompson

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.


(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. For such cases, use DecimalField is more practical. And I believe it is applied for most people. Using django-money as they highlighted, include Currency handling. So this is more for project involving transaction such as ecommerce sites, payment gateway, digital currency, banking, etc....
I'd argue that since they're working with USD -- a currency -- it makes more sense to use a currency-handling library like django-money (python-money) as it makes everything work as you'd expect and affords future feature adjustments. The original question says they need formatting and calculation (as you quoted) and for that you're better off using a currency library instead of a simple decimal field.
What if I want to add two money fields or do some calculations?
@saran3h you can work with money instances and perform calculations like any other number (decimal) instance. You can add/subtract, multiply by integers, etc.
L
Lee Hinde
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


J
J__

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

You do realize that you just created an infinite recursion loop in your property, right?
Interesting. May I ask how that it?
m
manuelpgs
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()

Beware of representing money as a floating point number, as people tend to get unhappy about rounding errors w.r.t. their money. See: stackoverflow.com/questions/3730019/… for more details.