1

次の Python クラスと Marshmallow スキーマ定義があります。

from marshmallow import Schema, fields, post_load

class Author:
    def __init__(self, id, name):
        self.id = id
        self.name = name


class Book:
    def __init__(self, id, author, name):
        self.id = id
        assert isinstance(author, Author)
        self.author = author
        self.name = name


class Library:
    def __init__(self, authors, books):
        self.authors = authors
        self.books = books


class AuthorSchema(Schema):
    id = fields.Int()
    name = fields.Str()

    @post_load
    def make_obj(self, data):
        return Author(**data)


class BookSchema(Schema):
    id = fields.Int()
    author_id = fields.Method('get_id', 'get_author', attribute="author")
    name = fields.Str()

    @post_load
    def make_obj(self, data):
        return Book(**data)

    def get_id(self, obj):
        return obj.author.id

    def get_author(self, value):
        return [a for a in authors if a.id == value][0]


class LibrarySchema(Schema):
    authors = fields.List(fields.Nested(AuthorSchema()))
    books = fields.List(fields.Nested(BookSchema()))

    @post_load
    def make_obj(self, data):
        return Library(**data)

    # preserve ordering of fields
    class Meta:
        ordered = True


def test_author_referencing():
    author1 = Author(1, "Astrid Lindgren")
    author2 = Author(2, "Tove Jansson")

    book1 = Book(11, author1, "The Brothers Lionheart")
    book2 = Book(12, author2, "Comet in Moominland")

    library = Library(authors=[author1, author2], books=[book1, book2])

    schema = LibrarySchema(strict=True)

    library_dict = schema.dump(library).data
    library2 = schema.load(library_dict).data

サンプルがうまく説明しているように、書籍オブジェクトに (著者 ID だけでなく) 著者への参照が含まれているが、著者 ID にシリアル化されるデータ モデルが必要です。

明らかに、シリアル化は問題ではありませんが、逆シリアル化するときは、著者リストの既に逆シリアル化された内容にアクセスする必要があります。マシュマロでそれを行う方法がよくわかりません。それは可能ですか?もちろん、この場合、Bookオブジェクトを数値の作成者 ID でインスタンス化し、@post_load操作を実行しLibrarySchemaて作成者 ID を参照に置き換えることはできますが、それは私には汚くて扱いにくいと感じます。助けてください。:-)

4

1 に答える 1

0

post_load でのデータのリンクは、まさにその方法です。

于 2016-11-30T23:57:50.453 に答える