[Django] #35642: After Upgrading from Django 2.2.28 to Django 3.2.25, JSONField is returning data in string rather than dictionary/list

20 views
Skip to first unread message

Django

unread,
Jul 30, 2024, 7:44:23 AM7/30/24
to django-...@googlegroups.com
#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.

Django

unread,
Jul 30, 2024, 7:50:53 AM7/30/24
to django-...@googlegroups.com
#35642: After Upgrading from Django 2.2.28 to Django 3.2.25, JSONField is returning
data in string rather than dictionary/list
-------------------------------------+-------------------------------------
Reporter: Bittu Ray | Owner: (none)
Type: Bug | Status: closed
Component: contrib.postgres | Version: 3.2
Severity: Normal | Resolution: invalid
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
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):

* resolution: => invalid
* severity: Release blocker => Normal
* status: new => closed

Comment:

Hello Bittu Ray! Thank you for your ticket. Please note that Django 2.2
and Django 3.2 are no longer supported, so I'll be closing this ticket
accordingly. If you can reproduce this issue in the latest Django 5.0,
please reopen with detailed instructions on how to reproduce.

The release notes of each version could also help you understand your
issue, specifically: https://docs.djangoproject.com/en/5.0/releases/3.1
/#jsonfield-for-all-supported-database-backends and
https://docs.djangoproject.com/en/5.0/releases/3.1/#deprecated-jsonfield
--
Ticket URL: <https://code.djangoproject.com/ticket/35642#comment:1>

Django

unread,
Jul 30, 2024, 9:13:25 AM7/30/24
to django-...@googlegroups.com
#35642: After Upgrading from Django 2.2.28 to Django 3.2.25, JSONField is returning
data in string rather than dictionary/list
-------------------------------------+-------------------------------------
Reporter: Bittu Ray | Owner: (none)
Type: Bug | Status: closed
Component: contrib.postgres | Version: 3.2
Severity: Normal | Resolution: invalid
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
-------------------------------------+-------------------------------------
Comment (by Simon Charette):

> 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

That's the crux of your issue; don't do that. JSON supports storing
strings as top level members so if you want objects to be stored pass
`dict` and not their JSON serialized form.
--
Ticket URL: <https://code.djangoproject.com/ticket/35642#comment:2>

Django

unread,
Aug 1, 2024, 7:21:45 AM8/1/24
to django-...@googlegroups.com
#35642: After Upgrading from Django 2.2.28 to Django 3.2.25, JSONField is returning
data in string rather than dictionary/list
-------------------------------------+-------------------------------------
Reporter: Bittu Ray | Owner: (none)
Type: Bug | Status: closed
Component: contrib.postgres | Version: 3.2
Severity: Normal | Resolution: invalid
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
-------------------------------------+-------------------------------------
Comment (by Bittu Ray):

Replying to [comment:2 Simon Charette]:
> > 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
>
> That's the crux of your issue; don't do that. JSON supports storing
strings as top level members so if you want objects to be stored pass
`dict` and not their JSON serialized form.

Hi, Even when I give input as dict, it's stored as a string instead of an
object in Postgres database. in django 2.2.28, it was getting stored as an
object. So even if I use dict, the data will still be stored as a string
in the Postgres.
--
Ticket URL: <https://code.djangoproject.com/ticket/35642#comment:3>
Reply all
Reply to author
Forward
0 new messages