I'm using a custom Django field to represent JSON encoded data:
class JSONField(models.TextField):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if value == "":
return None
try:
if isinstance(value, basestring):
return json_decode(value)
except ValueError:
pass
return value
def get_prep_value(self, value):
if value == "":
return None
if isinstance(value, dict) or isinstance(value, dict):
value = json_encode(value)
return super(JSONField, self).get_prep_value(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value,connection=None)
The field itself works fine. However editting via the admin site is not possible since the string from the database is JSON-decoded and converted to a dictionary, so when the admin site is rendered, not the actual JSON string from the database is displayed (e.g. {"foo": "bar"}), but its dictionary representation (e.g. {u'foo': u'bar'}).
Obviously this leads to problems when saving the database object, because the dictionary's string representation is not a valid JSON string.
What I'd like to have is the admin site showing the actual database value (i.e. the string as it is saved in the database), instead of the string representation of the Python object returned by to_python.
My attempt would be to write a custom widget for this that just calls json_encode again on the dictionary - but is there a better way?
value_from_object
will help solve the problem. It's implementation depends on what serializer has been used, but for simplejson should looks like:
from django.utils import simplejson as json
from django.core.serializers.json import DjangoJSONEncoder
class JSONField(models.TextField):
....
def value_from_object(self, obj):
return json.dumps(super(JSONField, self).value_from_object(obj))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With