#35642: After Upgrading from Django 2.2.28 to Django 3.2.25, JSONField is returning
data in string rather than dictionary/list
-------------------------------------+-------------------------------------
Reporter: raybittu | Type: Bug
Status: new | Component:
| contrib.postgres
Version: 3.2 | Severity: Release
| blocker
Keywords: jsonfield, django | Triage Stage:
3.2 | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
{{{
class CustomPatchedJSONFormField(JSONFormField):
def prepare_value(self, value):
"""
Exclude returning None in case of {}, returning None makes the
field empty when loaded
from admin instead of returning {},
which causes an error where empty dict was expected
"""
if value != {} and value in self.empty_values:
return None
elif isinstance(value, str):
return value
else:
return super(CustomPatchedJSONFormField,
self).prepare_value(value)
class CustomJSONField(JSONField):
"""
Overrides
1. `formfield` to set our custom JSON field as `form_class`
2. `from_db_value` to return a json from `str`
"""
def formfield(self, **kwargs):
defaults = {"form_class": CustomPatchedJSONFormField}
defaults.update(kwargs)
return super(JSONField, self).formfield(**defaults)
def from_db_value(self, value, expression, connection, context=None):
if isinstance(value, str):
try:
return json.loads(value)
except ValueError:
return value
return value
}}}
My Model
{{{
class MyModel(models.Model):
field1 = CustomJSONField(default=list)
}}}
when I am creating an object with dictionary as input, it's working
perfectly fine, but when I am creating the object input as str or
json.dumps, the output is also coming in string format rather than python
dictionary or list format
for example
{{{
MyModel.objects.create(field1={"key1:"value"})
a = MyModel.objects.get(id=1)
print(a.field1)
# It prints - {"key1:"value"}
# It's working fine and I am getting the output in dictionary format
# but when I try this :
MyModel.objects.create(field1='{"key1:"value"}')
a = MyModel.objects.get(id=1)
print(a.field1)
# It prints - '{"key1:"value"}'
# The value of field1 is in string format rather than dictionary format
}}}
I am using Postgres as my database and it was working fine till Django
2.2.28
--
Ticket URL: <
https://code.djangoproject.com/ticket/35642>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.