【问题标题】:TypeError when trying to JSON serialise a custom Django model field尝试 JSON 序列化自定义 Django 模型字段时出现 TypeError
【发布时间】:2012-06-15 11:05:16
【问题描述】:

我编写了一个自定义 Django 模型字段来存储 dateutil.relativedelta 的。该字段如下所示:

class RelativeDeltaField(models.CharField):
    description = "Relative delta"

    __metaclass__ = models.SubfieldBase

    max_length = 200

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = self.max_length
        super(RelativeDeltaField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if isinstance(value, relativedelta):
            return value

        try:
            return eval(value)
        except SyntaxError, e:
            logging.error("Mangled data for a relativedelta field. Was the data truncated in MySQL column? Either manually fix, or change the next line to 'return None' and manually fix. value=%r message=%r" % (value, e))
            raise

    def get_db_prep_save(self, value, connection):

        return repr(value)

    def value_to_string(self, obj):
        value = self._get_val_from_obj(obj)
        return self.get_prep_value(value)

我正在尝试将具有此字段的对象序列化为 json:

serializers.serialize('json', obj)

但我得到一个错误:

…
  File "/home/rory/tix/virtualenv/lib/python2.6/site-packages/django/core/serializers/json.py", line 58, in default
    return super(DjangoJSONEncoder, self).default(o)
  File "/usr/lib/python2.6/dist-packages/simplejson/encoder.py", line 190, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: relativedelta(hours=+1) is not JSON serializable

通过使用pdb,我可以看到在这种情况下o 是对象本身,它没有被转换为任何东西,也没有被序列化。

如何解决这个问题,以便我可以序列化我的字段?

Django 文档说 (https://docs.djangoproject.com/en/dev/howto/custom-model-fields/#converting-field-data-for-serialization) 添加一个 value_to_string,我确实有。

【问题讨论】:

  • 您到底希望它如何被序列化?您将使用什么格式将relativedelta(hours=+1) 表示为字符串?
  • 我希望 JSON 序列化器与数据库中的相同,即值的 repr,即它应该是字符串 "relativedelta(hours=+1)"

标签: python django json django-serializer django-custom-field


【解决方案1】:

文档中的代码只是一个样板,您需要实现value_to_string 以返回代表relativedelta 的字符串。

RelativeDeltaField 基于models.CharField,因此get_prep_value() 看起来像

def get_prep_value(self, value):
    return self.to_python(value)

CharField 可以,因为 Python 中该字段的预期值已经是一个字符串。但是,您的 to_python() 自定义版本返回 relativedelta 而不是字符串。

【讨论】:

  • 这似乎是问题所在。不知道为什么我只用了get_db_prep_value
猜你喜欢
  • 2021-08-05
  • 2014-10-05
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
相关资源
最近更新 更多