In my models.py, I have the following code:
from __future__ import unicode_literals
from django.db import models
from django.contrib.postgres.fields import JSONField
import json
class Table(models.Model):
name = models.CharField(max_length=255)
structure = JSONField(default=json.dumps('{}'))
def __unicode__(self):
return self.name
class Column(models.Model):
table = models.ForeignKey(Table, related_name='columns')
name = models.CharField(max_length=255)
required = models.BooleanField(default=True)
def __unicode__(self):
return self.name + ' FROM TABLE ' + self.table.name
def save(self, *args, **kwargs):
if not self.pk:
self.table.structure[self.name] = {
'required' : self.required,
}
As you can see from the code, when a Column is saved, if the column's required field gets added to the structure of the Table. However, when I try saving a column from the admin panel, I get the following error:
TypeError at /admin/myapp/column/add/
'unicode' object does not support item assignment
I think the problem is with the default value of my structure field. I also tried the following:
structure = JSONField(default={})
structure = JSONField(default='{}')
structure = JSONField(default=dict)
Each time, I got the same error. Any help? Thanks.
According to the doc, if you want the default to be a dict the right definition is JSONField(default=dict)
. Note that you may need to clean up your existing database - what has been stored as a unicode string (with your original definition) will STILL be unserialized as a unicode string.
Not that this is very cleary documented:
If you give the field a default, ensure it’s a callable such as dict (for an empty default) or a callable that returns a dict (such as a function). Incorrectly using default={} creates a mutable default that is shared between all instances of JSONField.
so you could have saved you some trouble by reading the doc first.