Nice programing

Django : FloatField 또는 DecimalField for Currency?

nicepro 2020. 11. 16. 22:10
반응형

Django : FloatField 또는 DecimalField for Currency?


어느 것이 통화 필드로 더 적합 할 지 궁금합니다. 차액, 기존 가격과 새 가격의 비율 등 간단한 작업을 수행합니다. 0 (즉 10.50) 뒤에 두 자리를 유지할 계획이며이 자리가 0이면 대부분의 경우이 숫자를 숨기고 "10"으로 표시합니다.

추신 : 통화는 달러 기반이 아닙니다. :)


항상 DecimalField돈을 위해 사용하십시오 . 단순한 연산 (더하기, 빼기)조차도 부동 반올림 문제에 영향을받지 않습니다.

>>> 10.50 - 0.20
10.300000000000001

>>> Decimal('10.50') - Decimal('0.20')
Decimal('10.30')

질문에 대한 대답은 정확하지만 일부 사용자는 DecimalField와 FloatField의 차이점을 찾기 위해이 질문을 우연히 발견합니다. Seth가 제기하는 유동 반올림 문제는 통화 문제입니다.

장고 문서 상태

FloatField 클래스는 때때로 DecimalField 클래스와 혼합됩니다. 둘 다 실수를 나타내지 만 그 숫자를 다르게 나타냅니다. FloatField는 내부적으로 Python의 float 유형을 사용하는 반면 DecimalField는 Python의 Decimal 유형을 사용합니다. 여기에서 더 많은 것을 읽으 십시오 .

두 필드의 다른 차이점은 다음과 같습니다.

DecimalField :

  • DecimalFields는 'decimal_places'및 'max_digits'속성을 정의해야합니다.
  • 위의 필수 속성에서 두 개의 자유 형식 유효성 검사가 여기에 포함됩니다. 즉, max_digits를 4로 설정하고 4.00000 (5 자리)의 10 진수를 입력하면 다음 오류가 발생합니다. 4 개 이하가 있는지 확인합니다. 총 자리수.
  • 또한 소수 자리에 대해 유사한 양식 유효성 검사를 수행합니다 (대부분의 브라우저에서 입력 필드의 단계 속성을 사용하여 프런트 엔드에서도 유효성을 검사합니다. decimal_places = 1을 설정하고 값으로 0.001을 입력하면 오류가 발생합니다) 최소값은 0.1이어야합니다.
  • 10 진수를 반환합니다 .Decimal, type is
  • DecimalField로 추가 유효성 검사가 없습니다.
  • Decimal 유형을 사용하면 위에서 설명한대로 설정해야하는 필수 속성으로 인해 반올림도 처리됩니다. 따라서 껍질에서
  • 데이터베이스 (postgresql)에서 DecimalField는 numeric (max_digits, decimal_laces) Type으로 저장되고 Storage는 "main"으로 설정됩니다. 위의 예에서 Type은 numeric (4,1)입니다.

Django Docs 에서 DecimalField 에 대해 자세히 알아보십시오 .

FloatField :

  • 내장 된 float 유형을 반환합니다.
  • 스마트 반올림이 없으며 실제로 Seths 답변에 설명 된대로 반올림 문제가 발생할 수 있습니다.
  • DecimalField에서 얻은 추가 양식 유효성 검사가 없습니다.
  • 데이터베이스 (postgresql)에서 FloatField는 "double precision"유형으로 저장되고 Storage는 "plain"으로 설정됩니다.

Django 문서 에서 FloatField대해 자세히 알아보세요 .

둘 다에 적용 :

  • 두 필드 모두 "Field"클래스에서 확장되며 'blank', 'null', 'verbose_name', 'name', 'primary_key', 'max_length', 'unique', 'db_index', 'rel', 'default ','editable ','serialize ','unique_for_date ','unique_for_month ','unique_for_year ','choices ','help_text ','db_column ','db_tablespace ','auto_created ','validators ','error_messages '속성 , "필드"에서 확장되는 모든 필드가 가질 수 있습니다.
  • 두 필드의 기본 양식 위젯은 TextInput입니다.

나는 두 분야의 차이점을 찾을 때이 질문을 보았으므로 동일한 상황에있는 사람들에게 도움이 될 것이라고 생각합니다. :)

업데이트 : 질문에 답하기 위해 Decimal이 훨씬 더 적합하지만 통화를 나타 내기 위해 둘 중 하나를 사용할 수 있다고 생각합니다. float로 계산 될 때 반올림 문제가 있으므로 round(value, 2)float 표현을 소수점 이하 두 자리로 반올림하기 위해 사용해야 합니다. 다음은 간단한 예입니다.

>>> round(1.13 * 50 + .01, 2)
56.51

플로트 및 라운드에 여전히 문제가 발생할 수 있습니다. 여기처럼 5의 값으로 반 내림하는 것을 볼 수 있습니다.

>>> round(5.685, 2)
5.68

그러나이 경우 반올림됩니다.

>>> round(2.995, 2)
3.0

플로트가 메모리에 저장되는 방법과 관련이 있습니다. 를 참조하십시오 여기 .


편집 : Satchmo 프로젝트는 더 이상 활성화되지 않으므로 통화 처리를위한 다음 대안을 살펴보십시오.


Django 기반 Satchmo 프로젝트 에는 살펴볼 가치가있는 CurrencyField 및 CurrencyWidget이 있습니다.

Check out the satchmo_utils app directory for the source


I know this is super old, but I stumbled on it looking for something completely different, and I wanted to throw out there that in general it is inadvisable to use floating point numbers (float or decimal) for currency, as floating point math rounding will invariably lead to small errors in calculation that can add up to very large discrepancies over time.

Instead, use an integer field or a string at your preference. Multiply your currency to move the decimal place to the end and make a whole number when you store it, and then move that decimal place back where it belongs when you need to show it. This is basically how banks (and most currency libraries) handle storing data and will save you loads of trouble later on.

I learned this the hard way because it's not really a common topic; maybe this saves someone else from doing the same thing.

참고URL : https://stackoverflow.com/questions/2569015/django-floatfield-or-decimalfield-for-currency

반응형