django-json-field
django-json-field copied to clipboard
Why decimal?
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?
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.
Is this still an open issue? What's the best workaround in the meanwhile?
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})
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?
+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.
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()