0

を格納するカスタム 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に記載されていますが、これは私が持っています。

4

1 に答える 1

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は文字列ではありません。

于 2012-06-15T11:54:14.417 に答える