Was ist das beste Django-Modellfeld, um einen US-Dollar-Betrag darzustellen?

103

Ich muss einen US-Dollar-Betrag in einem Feld eines Django-Modells speichern. Was ist der beste Modellfeldtyp? Ich muss in der Lage sein, den Benutzer diesen Wert eingeben zu lassen (bei Fehlerprüfung möchte er nur eine auf Cent genaue Zahl), ihn für die Ausgabe an Benutzer an verschiedenen Orten zu formatieren und ihn zur Berechnung anderer Zahlen zu verwenden.

MikeN
quelle

Antworten:

166

Ein Dezimalfeld ist die richtige Wahl für den Währungswert.

Es wird ungefähr so ​​aussehen:

credit = models.DecimalField(max_digits=6, decimal_places=2)
einfach hart
quelle
98
Es sei denn, Sie möchten die Staatsverschuldung darstellen. In diesem Fall muss max_digits> 20 sein
Bron Davies
4
decimal_places = 2 ist nicht unbedingt korrekt, wenn Sie dies zur Unterstützung anderer Währungen benötigen. Einige Währungen haben drei Dezimalstellen, und Bitcoin hat eine Keuchhusten 8.
Lie Ryan
2
Ich denke, dieses Beispiel ist fast für alle Währungen korrekt. Um Währungen als Bitcoin darzustellen, ist es meiner Meinung nach viel besser, ein ganzzahliges Feld zu verwenden, um den Betrag in Satoshis zu speichern und ihn dann dem Endbenutzer in der gewünschten Darstellung (BTC, mBTC usw.)
anzuzeigen
Es sei denn, Sie möchten die Staatsverschuldung von Venezuela in der Landeswährung von Venezuela darstellen. In diesem Fall benötigen Sie 21 max_digits
Luis Sieira
@LieRyan das stimmt. Wir müssen moderne Arten von "Währungen" zur Kenntnis nehmen, um zukünftige Änderungen der Datenbank zu verhindern. Keine Beleidigung für die Verwendung von Zitaten.
Enchance
35

Die anderen Antworten sind zu 100% richtig, aber nicht sehr praktisch, da Sie die Ausgabe, Formatierung usw. noch manuell verwalten müssen.

Ich würde vorschlagen, Django-Geld zu verwenden :

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,
    )

Funktioniert automatisch aus Vorlagen:

{{ somemodel.some_currency }}

Ausgabe:

$123.00

Es hat ein leistungsfähiges Backend über Python-Money und ist im Wesentlichen ein Ersatz für Standard-Dezimalfelder.

Michael Thompson
quelle
(Mit der Fehlerprüfung möchten Sie nur eine auf Cent genaue Zahl), formatieren Sie sie für die Ausgabe an Benutzer an verschiedenen Orten und verwenden Sie sie zur Berechnung anderer Zahlen. In solchen Fällen ist die Verwendung DecimalFieldpraktischer. Und ich glaube, es wird für die meisten Menschen angewendet. Verwenden django-moneySie, wie hervorgehoben, die Währungsbehandlung . Dies ist also eher für Projekte mit Transaktionen wie E-Commerce-Websites, Zahlungsgateway, digitaler Währung, Bankgeschäften usw.
Yeo
Ich würde argumentieren, dass es sinnvoller ist, eine währungsbearbeitende Bibliothek wie Django-Geld (Python-Geld) zu verwenden, da sie mit USD - einer Währung - arbeiten, da alles so funktioniert, wie Sie es erwarten und sich leisten können zukünftige Funktionsanpassungen. Die ursprüngliche Frage besagt, dass sie formatiert und berechnet werden müssen (wie Sie angegeben haben). Dafür ist es besser, eine Währungsbibliothek anstelle eines einfachen Dezimalfelds zu verwenden.
Michael Thompson
1
Was ist, wenn ich zwei Geldfelder hinzufügen oder einige Berechnungen durchführen möchte?
Saran3h
1
@ saran3h Sie können mit Geldinstanzen arbeiten und Berechnungen wie jede andere Zahl (dezimal) durchführen. Sie können addieren / subtrahieren, mit ganzen Zahlen multiplizieren usw.
Michael Thompson
8

Definieren Sie eine Dezimalstelle und geben Sie ein $ -Zeichen vor dem Wert zurück.

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

    @property
    def price_display(self):
        return "$%s" % self.price
Çagatay Melan
quelle
6
Sie erkennen, dass Sie gerade eine Endlosrekursionsschleife in Ihrer Eigenschaft erstellt haben, oder?
El Ninja Trepador
Interessant. Darf ich fragen, wie das geht?
Kingraphaii
2
field = models.DecimalField(max_digits=8, decimal_places=2)

Sollte ein Feld für PostgreSQL erstellen wie:

 "field" numeric(8, 2) NOT NULL

Welches ist der beste Weg für PostGreSQL gespeicherten US-Dollar-Betrag.

Wenn Sie einen PostgreSQL-Feldtyp "doppelte Genauigkeit" benötigen, müssen Sie dies im Django-Modell tun:

field = models.FloatField()
Held
quelle
3
Achten Sie darauf, Geld nicht als Gleitkommazahl darzustellen, da die Leute über Rundungsfehler in Bezug auf ihr Geld eher unglücklich werden. Weitere Informationen finden Sie unter: stackoverflow.com/questions/3730019/… .
Adam Parkin