""" taken from http://www.djangosnippets.org/snippets/377/ """ import datetime from django.db import models from django.db.models import signals from django.conf import settings from django.utils import simplejson as json from django.core.serializers.json import DjangoJSONEncoder class JSONField(models.TextField): """JSONField is a generic textfield that neatly serializes/unserializes JSON objects seamlessly""" # Used so to_python() is called __metaclass__ = models.SubfieldBase def __init__(self, json_type=None, **kwargs): self.json_type = json_type super(JSONField, self).__init__(**kwargs) def to_python(self, value): """Convert our string value to JSON after we load it from the DB""" # must handle the case where the value is already ready if self.json_type: if isinstance(value, self.json_type): return value else: if isinstance(value, dict) or isinstance(value, list): return value if value == "" or value == None: return None parsed_value = json.loads(value) if self.json_type and parsed_value: parsed_value = self.json_type.fromJSONDict(parsed_value) return parsed_value # we should never look up by JSON field anyways. # def get_prep_lookup(self, lookup_type, value) def get_prep_value(self, value): """Convert our JSON object to a string before we save""" if isinstance(value, basestring): return value if value == None: return None if self.json_type or hasattr(value,'toJSONDict'): the_dict = value.toJSONDict() else: the_dict = value return json.dumps(the_dict, cls=DjangoJSONEncoder) def value_to_string(self, obj): value = self._get_val_from_obj(obj) return self.get_db_prep_value(value) ## ## for schema migration, we have to tell South about JSONField ## basically that it's the same as its parent class ## from south.modelsinspector import add_introspection_rules add_introspection_rules([], ["^auth\.jsonfield\.JSONField"])