2010-10-26 12 views
7

Estoy sacando una suma de un DB que es un valor decimal. estoy tratando de utilizar ese valor en un resultado JSONDecimal a JSON

json.dumps({ 'sum': amount }) #where amount is my Decimal 

Django no puede serializar el Decimal. Puedo convertirlo en una cadena, pero me gustaría un tipo numérico dentro de la JSON. Si intento convertirlo a un float termino con más de 2 lugares decimales.

¿Qué debe suceder, si es posible, para obtener un resultado como el siguiente?

{ 'sum': 500.50 } 
+0

No sé mucho acerca de Django, pero si necesita dos decimales siempre y no es posible hacer exactamente lo que quiero que puedas multiplicar por 100 y trabajar con él como un entero. – cambraca

+1

JSON solo está definido para tener flotantes de precisión doble para números. ¿Qué te compra para mantener tus números como decimales? – Gabe

+0

No necesito que mis números sean decimales, nunca serán tan grandes. Eso es lo que obtengo de la base de datos, ya que son valores monetarios. No estaba entusiasmado con el uso de int * 100 y las flotantes me dan más de dos decimales. Solo esperaba que hubiera una solución más elegante ... – Justin

Respuesta

11

Lo que puede hacer es extender la clase JSONDecoder para proporcionar un serializador personalizado para el tipo decimal, similar al ejemplo de este documento: http://docs.python.org/py3k/library/json.html

>>> import json 
>>> class DecimalEncoder(json.JSONEncoder): 
...  def default(self, obj): 
...   if isinstance(obj, Decimal): 
...    return "%.2f" % obj 
...   return json.JSONEncoder.default(self, obj) 
... 

Eso es un ejemplo no laborable de cómo hacer es, con suerte, un buen punto de partida para ti.

+0

Gracias, esta es la mejor solución hasta el momento :) – Justin

+10

Actualmente Django proporciona una clase incorporada para esto: 'django.core.serializers.json.DjangoJSONEncoder '- que puede usar directamente haciendo' simplejson.dumps (mydict, class = DjangoJSONEncoder) '. También se ocupa de las fechas. –

+3

@Daniel Gracias. 'class = DjangoJSONEncoder' debe ser 'cls = DjangoJSONEncoder'. Esto funciona, pero me da un valor de cadena :( – Justin

0

No existe un tipo de Decimal en Javascript, y también entre los tipos estándar en python. Es un tipo de base de datos específica y no parte de JSON. Toma Float o haz una aritmética de enteros.

+0

Sí, sé que no hay ningún tipo de coincidencia en JavaScript, mis valores nunca serán tan grandes. Simplemente quiero que bajen en un formato monetario normal "5.95", pero no en formato de cadena. – Justin

0

decimal se puede convertir a un flotador que Javascript sabe cómo tratar con

json.dumps({ 'sum': float(amount) }) 
+0

En mi pregunta, noté que no quería pasar un flotante debido a que tenían una gran cantidad de decimales. – Justin