Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.9 JSONfield stored dictionary returns unicode instead

Tags:

python

django

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?

like image 870
Dissipia Avatar asked Apr 01 '16 09:04

Dissipia


3 Answers

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()
like image 160
Igor Atsberger Avatar answered Oct 12 '22 23:10

Igor Atsberger


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.

like image 45
stelios Avatar answered Oct 12 '22 23:10

stelios


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;
like image 20
Kevin Marcelo Avatar answered Oct 13 '22 00:10

Kevin Marcelo