documentacion - Django: FloatField o DecimalField for Currency?
django models select field (4)
La respuesta a la pregunta es correcta; sin embargo, algunos usuarios tropezarán con esta pregunta para descubrir la diferencia entre DecimalField y FloatField. El problema de redondeo de flotación que Seth plantea es un problema para la divisa.
Los Estados de Django Docs
La clase FloatField a veces se confunde con la clase DecimalField. Aunque ambos representan números reales, representan esos números de manera diferente. FloatField usa el tipo de letra flotante de Python internamente, mientras que DecimalField usa el tipo de letra decimal de Python. Lea más here .
Aquí hay otras diferencias entre los dos campos:
DecimalField:
- DecimalFields debe definir un atributo ''decimal_places'' y un atributo ''max_digits''.
- Obtendrá dos validaciones de forma libre incluidas aquí de los atributos requeridos anteriormente, es decir, si establece max_digits en 4 y escribe un decimal que es 4.00000 (5 dígitos), obtendrá este error: Asegúrese de que no haya más de 4 dígitos en total.
- También obtiene una validación de formulario similar para decimales (que en la mayoría de los navegadores también validará en el front end utilizando el atributo step en el campo de entrada. Si establece decimal_places = 1 y escribe 0.001 como valor obtendrá un error que el valor mínimo tiene que ser 0.1.
- Devuelve un decimal.Decimal, tipo es
- No tiene la validación adicional como DecimalField
- Con un tipo de Decimal, el redondeo también se maneja por usted debido a los atributos requeridos que deben establecerse como se describe anteriormente. Entonces desde el caparazón, si
- En la base de datos (postgresql), el DecimalField se guarda como un tipo numérico (max_digits, decil_laces) Type, y Storage se establece como "main", del ejemplo anterior, el Type es numérico (4,1)
Más sobre DecimalField de Django Docs .
FloatField:
- Devuelve el tipo de flotador incorporado
- No hay redondeo inteligente, y en realidad puede dar como resultado problemas de redondeo como se describe en la respuesta de Seth.
- No tiene la validación de formulario adicional que obtienes de DecimalField
- En la base de datos (postgresql), FloatField se guarda como un tipo de "doble precisión", y el almacenamiento se establece como "simple"
Más sobre FloatField de Django Docs .
Se aplica a Ambos:
- Ambos campos se extienden desde la clase "Field" y pueden aceptar ''blank'', ''null'', ''verbose_name'', ''name'', ''primary_key'', ''max_length'', ''unique'', ''db_index'', ''rel'', ''default atributos '','' editable '','' serializar '','' unique_for_date '','' unique_for_month '','' unique_for_year '','' choices '','' help_text '','' db_column '','' db_tablespace '','' auto_created '','' validators '','' error_messages '' , como todos los campos que se extienden desde "Campo" tendrían.
- El widget de formulario predeterminado para ambos campos es un TextInput.
Me encontré con esta pregunta cuando busqué la diferencia entre los dos campos, así que creo que esto ayudará a aquellos en la misma situación :)
ACTUALIZACIÓN: para responder a la pregunta, creo que puede salirse con la suya ya sea para representar la moneda, aunque Decimal es un ajuste mucho mejor. Hay un problema de redondeo cuando cuenta para flotar, por lo que debe usar una round(value, 2)
para mantener su representación de flotante redondeada a dos decimales. Aquí hay un ejemplo rápido:
>>> round(1.13 * 50 + .01, 2)
56.51
Todavía puede tener problemas con flotador y ronda. Al igual que aquí, vemos que redondea a un valor de 5:
>>> round(5.685, 2)
5.68
Pero en este caso, se redondeará:
>>> round(2.995, 2)
3.0
Tiene todo que ver con cómo se almacena el flotador en la memoria. Mira here .
Tengo curiosidad de saber cuál sería más apropiado como campo monetario. Haré operaciones simples como tomar la diferencia, el porcentaje entre los precios antiguos y los nuevos. Planeo mantener dos dígitos después del cero (es decir, 10.50) y la mayoría del tiempo si estos dígitos son cero, ocultaré estos números y lo mostraré como "10"
PD: La moneda NO está basada en dólares :)
Sé que esto es muy antiguo, pero me encontré con que buscaba algo completamente diferente, y quería decir que, en general, no es aconsejable usar números de punto flotante (flotante o decimal) para la moneda, ya que el redondeo matemático de coma flotante invariablemente conducen a pequeños errores en el cálculo que pueden sumar grandes discrepancias a lo largo del tiempo.
En su lugar, use un campo entero o una cadena según su preferencia. Multiplique su moneda para mover el lugar decimal al final y haga un número entero cuando lo almacene, y luego mueva ese lugar decimal a donde pertenece cuando necesite mostrarlo. Esto es básicamente cómo los bancos (y la mayoría de las bibliotecas de divisas) manejan el almacenamiento de datos y le ahorrará muchos problemas más adelante.
Aprendí esto de la manera difícil porque no es realmente un tema común; tal vez esto le ahorra a alguien más hacer lo mismo.
editar: El Proyecto Satchmo ya no está activo, así que eche un vistazo a estas alternativas para manejar la divisa
El Proyecto Satchmo basado en Django tiene un CurrencyField y CurrencyWidget que vale la pena echarle un vistazo.
Consulte el directorio de la aplicación satchmo_utils para la fuente
Siempre use DecimalField
por dinero. Incluso las operaciones simples (suma, resta) no son inmunes a los problemas de redondeo de flotación:
>>> 10.50 - 0.20
10.300000000000001
>>> Decimal(''10.50'') - Decimal(''0.20'')
Decimal(''10.30'')