2015-12-23 1 views
0

je les définitions de schéma classe Python et Marshmallow suivants:Accéder à des données désérialisées à partir de champs frères dans 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 

Comme l'échantillon illustre tout va bien, je voudrais avoir un modèle de données dans lequel les objets de livres contiennent des références aux auteurs (au lieu de seulement ids de l'auteur) , mais qui serait sérialisé en identifiant d'auteur.

De toute évidence, la sérialisation n'est pas un problème, mais lors de la désérialisation, je dois accéder au contenu déjà désérialisé de la liste des auteurs. Je n'arrive pas à comprendre comment faire ça avec Marshmallow. Est-ce même possible? Bien sûr, dans ce cas, je pourrais instancier Book objets avec des identifiants d'auteurs numériques et faire une opération @post_load en LibrarySchema pour remplacer l'identifiant de l'auteur par une référence, mais cela me semble sale et maladroit. S'il vous plaît aider. :-)

Répondre

0

Lier des données dans post_load est exactement comme vous devriez le faire.