django-json-field icon indicating copy to clipboard operation
django-json-field copied to clipboard

Why decimal?

Open ivoras opened this issue 12 years ago • 6 comments
trafficstars

I've noticed that django-json-field treats my floating point data as Decimal type. I've seen why you did it by looking at the issues history of the project on GitHub, but I think it's really inconvenient, here's why:

  • Python's default fast JSON encoder (json.dumps) written in C chokes when I give it data I got from a JSONField field (as a part of a larger structure), forcing me to use a custom encoder in Python, which is orders of magnitude slower.
  • Decimal data type itself is hugely slower than float
  • All modern browsers treat the JavaScript "number" type internally as a double precision float, so the added precision of Decimal is lost when transferred to the browser. JSON is not JavaScript, but you must admit it's most commonly used as such.

Could you make an option to be used in the field declaration to treat floats as floats? E.g. f = JSONField(null=True, pure_float=True)

... or something like it?

ivoras avatar Sep 15 '13 10:09 ivoras

Yup all of that is true, it's not a perfect solution. I think adding an option/toggle is probably the best way to appease all parties.

derek-schaefer avatar Oct 04 '13 21:10 derek-schaefer

Is this still an open issue? What's the best workaround in the meanwhile?

alexbw avatar Jan 05 '14 02:01 alexbw

It is, however this will get you most of the way there:

from json_field import JSONField
from json_field.fields import JSONDecoder

class Test(models.Model):

    json = JSONField(decoder_kwargs={'cls':JSONDecoder, 'parse_float':float})

derek-schaefer avatar Jan 15 '14 03:01 derek-schaefer

Adding those decoder_kwargs to each model field seems to be the only way to get the admin form field to save float/decimal values as numbers, rather than strings. Any way that can be made the default behavior?

jacobg avatar Jul 15 '14 17:07 jacobg

+1 on this. My application is such that it's trying to compare Decimal to float's and raising exceptions. I've specified decoder_kwargs like you say above but it's inconvenient. I'd love to see a setting JSON_FIELD_PARSE_FLOAT. You could leave it as decimal but then I could easily override in my settings.py.

I'd be willing to do the legwork and submit a pull request if you give me the go-ahead.

audleman avatar Nov 03 '14 22:11 audleman

My 2¢:

Global settings are a very bad idea for this kind of thing - different applications that use django-json-field might want different values of the setting.

Why is specifying keyword arguments inconvenient? If you dislike repeating it every time, then don't repeat it every time - just write your own wrapper:

# utils file
from json_field import JSONField
from json_field.fields import JSONDecoder

make_json_field = lambda: JSONField(decoder_kwargs={'cls':JSONDecoder, 'parse_float':float})

# models:
from . utils import make_json_field

class MyModel(Model):
    json = make_json_field()

spookylukey avatar Jun 27 '15 13:06 spookylukey