Reputation: 6298
I've been getting my feet wet with using hstore in Django, through the django-hstore
module. A big advantage to using hstore
is that it allows for key-values to be stored in a field while providing decent indexing in Postgresql. A big disadvantage to django-hstore
(and hstore
in general) is that you can only store values as strings.
To overcome this, I thought it would be nice to override the model field (hstore.DictionaryField
) so that any data entered in to the field is automatically encoded in JSON and any data retrieved is automatically decoded from JSON. I've attempted to do this by overriding the __setattr__
method but this causes tons of errors (when all the properties of the field are being set). Any ideas of the right way to do this?
What I have so far (I've commented out the getter portions while focusing on the setter, but left it in to show what I had in mind):
import simplejson as json
from django.db import models
from django_hstore import hstore
def _unpack_json(value):
try:
value = json.loads(value)
except TypeError:
pass
return value
class HStoreJsonDict(hstore.DictionaryField):
@staticmethod
def _load_json(value):
try:
value = json.dumps(value)
except Exception as e:
# Is this needed?
print(value, e)
pass
return value
# def __getattribute__(self, key):
# print('__getattribute__')
# value = super(HStoreJsonDict, self).__getattribute__(key)
# return _unpack_json(value)
# def __getitem__(self, key):
# print('__getitem__')
# value = super(HStoreJsonDict, self).__getitem__(key)
# return _unpack_json(value)
def __setattr__(self, key, value):
print('__setattr__', key, value)
value = self._load_json(value)
return super(HStoreJsonDict, self).__setattr__(key, value)
class TestModel(models.Model):
name = models.CharField(max_length=64)
data = HStoreJsonDict(db_index=True)
objects = hstore.HStoreManager()
def __unicode__(self):
return '%s - %s' % (self.name, self.data)
Upvotes: 2
Views: 1263
Reputation: 6298
At the end of the day, I found it easiest to fork the django-hstore
module and to put serialization/deserialization in the DictionaryField
's get_prep_value()
and to_python()
methods (see here for code).
For anyone else looking to manipulate data on entry-to/retrieval-from the database when using Django, I highly recommend checking Django's docs on to_python() and get_prep_value().
Upvotes: 1