1

私のモデルにはすべて、モデルを辞書に変換するメソッドがあります。

def to_dict(model):
    output = {}
    SIMPLE_TYPES = (int, long, float, bool, dict, basestring, list)
    for key, prop in model._properties.iteritems():
        value = getattr(model, key)

        if value is None:
            continue
        if isinstance(value, SIMPLE_TYPES):
            output[key] = value
        elif isinstance(value, datetime.date):
            dateString = value.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
            output[key] = dateString
        elif isinstance(value, ndb.Model):
            output[key] = to_dict(value)
        else:
            raise ValueError('cannot encode ' + repr(prop))
    return output

さて、私のモデルの 1 つ には、次のものXがありLocalStructuredPropertyます。

metaData = ndb.LocalStructuredProperty(MetaData, repeated=True)

したがって、repeated=True は、これが MetaData オブジェクトのリストになることを意味します。MetaDataは別のモデルで、こちらも同じto_dict方法です。

ただし、 を呼び出すとjson.dumps(xInstance.to_dict())、例外が発生します。

raise TypeError(repr(o) + " is not JSON serializable")
TypeError: MetaData(count=0, date=datetime.datetime(2012, 9, 19, 2, 46, 56, 660000), unique_id=u'8E2C3B07A06547C78AB00DD73B574B8C') is not JSON serializable

どうすればこれを処理できますか?

4

3 に答える 3

2

to_dict()これを JSON にシリアライズする前のレベルで処理したい場合は、 to_dict(). まず、to_dict上記の定義はメソッドだとおっしゃいました。ints関数または staticmethod に委譲して、最初に型をチェックせずに呼び出すことができるようにします。そうすれば、コードはより良くなります。

def coerce(value):
    SIMPLE_TYPES = (int, long, float, bool, basestring)
    if value is None or isinstance(value, SIMPLE_TYPES):
        return value
    elif isinstance(value, datetime.date):
        return value.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
    elif hasattr(value, 'to_dict'):    # hooray for duck typing!
        return value.to_dict()
    elif isinstance(value, dict):
        return dict((coerce(k), coerce(v)) for (k, v) in value.items())
    elif hasattr(value, '__iter__'):    # iterable, not string
        return map(coerce, value)
    else:
        raise ValueError('cannot encode %r' % value)

to_dict次に、それをメソッド自体にプラグインします。

def to_dict(model):
    output = {}
    for key, prop in model._properties.iteritems():
        value = coerce(getattr(model, key))
        if value is not None:
            output[key] = value
    return output
于 2012-09-19T15:48:53.557 に答える
1

シリアル化するために必要なのは、関数を実装することだけです

def default_encode(obj):
    return obj.to_dict()

次に、JSONをでエンコードします

json.dumps(X.to_dict(), default=default_encode)
于 2012-09-19T03:43:10.880 に答える
0

この問題を解決する方法を見つけました。X クラスで、これを to_dict() メソッドに追加します。

            ...         
            if value is None:
                continue
            if key == 'metaData':
                array = list()
                for data in value:
                    array.append(data.to_dict())
                output[key] = array
            elif isinstance(value, SIMPLE_TYPES):
                output[key] = value
            ...

キーに基づいていないこのケースを自動化する方法はよくわかりませんが、カスタムオブジェクトのリストに遭遇するたびに、最初にリスト内の各オブジェクトを最初に to_dict() に変換します。

于 2012-09-19T15:37:47.347 に答える