在Django管理站点中使用forms.TextArea作为自定义JSON字段

时间:2011-12-23 02:37:10

标签: django django-admin

我正在使用自定义Django字段来表示JSON编码数据:

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)

该领域本身运作良好。但是,由于来自数据库的字符串是JSON解码并转换为字典,因此无法通过管理站点进行编辑,因此在呈现管理站点时,不会显示数据库中的实际JSON字符串(例如{“foo”: “bar”}),但它的字典表示(例如{u'foo':u'bar'})。

显然,这会在保存数据库对象时导致问题,因为字典的字符串表示形式不是有效的JSON字符串。

我想要的是管理站点显示实际的数据库值(即保存在数据库中的字符串),而不是to_python返回的Python对象的字符串表示。

我的尝试是为此编写一个自定义小部件,只需在字典上再次调用json_encode - 但是有更好的方法吗?

1 个答案:

答案 0 :(得分:5)

value_from_object将有助于解决问题。它的实现取决于使用了什么序列化器,但对于simplejson应该如下:

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))