Qual è il miglior campo del modello Django da utilizzare per rappresentare un importo in dollari USA?


104

Devo memorizzare un importo in dollari USA in un campo di un modello Django. Qual è il miglior tipo di campo del modello da utilizzare? Devo essere in grado di consentire all'utente di inserire questo valore (con il controllo degli errori, voglio solo un numero preciso al centesimo), formattarlo per l'output agli utenti in luoghi diversi e usarlo per calcolare altri numeri.

Risposte:


167

Un campo decimale è la scelta giusta per il valore della valuta.

Assomiglierà a:

credit = models.DecimalField(max_digits=6, decimal_places=2)

100
A meno che tu non voglia rappresentare il debito nazionale, nel qual caso max_digits deve essere> 20
Bron Davies

4
decimal_places = 2 non è necessariamente corretto se serve per supportare altre valute. Alcune valute hanno tre cifre decimali e Bitcoin ha un enorme 8.
Lie Ryan

2
Penso che questo esempio sia corretto per quasi tutte le valute. Per rappresentare le valute come Bitcoin, penso che sia molto meglio usare un campo intero per salvare l'importo in satoshi, e poi mostrarlo all'utente finale nella rappresentazione che desideri (BTC, mBTC, ecc.)
jion

A meno che tu non voglia rappresentare il debito nazionale del venezuela, nella valuta nazionale venezuelana, nel qual caso hai bisogno di 21 max_digits
Luis Sieira

@LieRyan è vero. Dobbiamo prendere nota dei moderni tipi di "valuta" per evitare future modifiche al database. Senza offesa per l'uso delle virgolette.
Enchance


35

Le altre risposte sono corrette al 100% ma non sono molto pratiche in quanto dovrai comunque gestire manualmente l'output, la formattazione, ecc.

Suggerirei di usare 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,
    )

Funziona automaticamente dai modelli:

{{ somemodel.some_currency }}

Produzione:

$123.00

Ha un potente backend tramite denaro python ed è essenzialmente un sostituto immediato per i campi decimali standard.


(con il controllo degli errori, desideri solo un numero preciso in centesimi), formattalo per l'output agli utenti in luoghi diversi e usalo per calcolare altri numeri. In questi casi, l'uso DecimalFieldè più pratico. E credo che sia applicato alla maggior parte delle persone. Usando django-moneycome hanno evidenziato, includi la gestione della valuta . Quindi questo è più per progetti che coinvolgono transazioni come siti di e-commerce, gateway di pagamento, valuta digitale, servizi bancari, ecc ...
Yeo

Direi che dal momento che stanno lavorando con USD - una valuta - ha più senso utilizzare una libreria per la gestione della valuta come django-money (python-money) poiché fa funzionare tutto come ti aspetteresti e offre future modifiche alle funzionalità. La domanda originale dice che hanno bisogno di formattazione e calcolo (come hai citato) e per questo è meglio usare una libreria di valute invece di un semplice campo decimale.
Michael Thompson

1
E se volessi aggiungere due campi denaro o eseguire alcuni calcoli?
saran3h

1
@ saran3h puoi lavorare con istanze di denaro ed eseguire calcoli come qualsiasi altra istanza numerica (decimale). Puoi aggiungere / sottrarre, moltiplicare per numeri interi, ecc.
Michael Thompson

9

Definisci un decimale e restituisci un segno $ davanti al valore.

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

    @property
    def price_display(self):
        return "$%s" % self.price

6
Ti rendi conto che hai appena creato un ciclo di ricorsione infinito nella tua proprietà, giusto?
El Ninja Trepador

Interessante. Posso chiederti come mai?
kingraphaii

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

Dovrebbe creare un campo per PostgreSQL come:

 "field" numeric(8, 2) NOT NULL

Qual è il modo migliore per archiviare l'importo in dollari USA di PostGreSQL.

Se hai bisogno di un campo PostgreSQL di tipo "double precision", allora devi farlo nel modello django:

field = models.FloatField()

3
Attenzione a rappresentare il denaro come un numero in virgola mobile, poiché le persone tendono a non essere contente degli errori di arrotondamento rispetto ai loro soldi. Vedi: stackoverflow.com/questions/3730019/… per maggiori dettagli.
Adam Parkin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.