We've just upgraded to Django 1.9 and moved things to its built-in JSONfield, which we use to store a dictionary. However, when I try to read data from it, it returns unicode of the dictionary instead.
My JSONfield is defined as:
class SmsInfo(models.Model):
[...]
json = JSONField(default=dict)
Data is written to it by:
params = dict(request.POST)
SmsInfo.objects.create([...], json=params, [...])
It is later read in this way:
incoming_smsses = SmsInfo.objects.select_related('game').defer('game__serialized').filter([...])
At which point:
print incoming_smsses[0].json.__class__
returns
<type 'unicode'>
instead of the dict I am expecting and my code crashes because it can't look up any keys.
I've been stuck on this for quite a bit, and I can't figure out why this is going wrong. I've used literal_eval as a workaround for now, which turns the unicode back into a dict. That works for now, but I'd rather tackle this at the source!
Why is my dictionary being turned to unicode here?
I just went through upgrading from a third-party JSONField to the native postgres JSONField and found through psql that the column type is still text
.
So on psql, confirm your column type:
\d+ table_name
And alter the column if it's still text:
ALTER TABLE table_name ALTER COLUMN column_name TYPE jsonb USING column_name::jsonb;
As suggested by erickw in comments, this has been filed as a bug: https://code.djangoproject.com/ticket/27675
If you happened to use django-jsonfield
before, there is a conflict between them, thus as the bug above suggests, the solution is to completely delete and remake the migration files of the app which uses the jsonfield.
In that case, apparently you would like to uninstall django-jsonfield
as well.
I'm using Django 1.11 and postgres 11.4.
Passing list of python dicts to JSONField worked for me:
data_python = []
for i in range(3):
entry = {
'field1': value1,
'field2': 999,
'field3': 'aaaaaaaaaa',
'field4': 'never'
}
data_python.append(entry)
MyModel.objects.create(data=data_python, name='DbEntry1')
My guess is that for dicts this should work as well
And my model is:
class MetersWithNoReadings(models.Model):
created_datetime = models.DateTimeField(auto_now_add=True)
updated_datetime = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=25)
data = JSONField()
As @stelios points out, this is a bug with django-jsonfield
which is not compatible with the native version.
Either:
django-jsonfield
(if it is no longer required as a project dependency, you can check with pipdeptree
), or django-jsonfield >= 1.3.0
since the issue is now closed and the fix merged. Seems related to DB storage here. Still this JSONField acts as a validator for proper JSON formatting.
However, you can hack around and load a dict from this returned unicode string.
Try as follow :
import json
data = json.loads(incoming_smsses[0].json)
Then you can access it as a dict IMO.
You need to use native postgres JSONField
from django.contrib.postgres import fields
class Some_class(models.Model):
json = fields.JSONField()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.