I'm working on an API that handles nested data structures. When trying to use marshmallow i'm having trouble coming up with a solution to creating nested model instances with references to their parent instance. Marshmallow's post_load operates from the child to the parent in that order instead of parent to child. Is there a way to reverse this? I'd like to start with serializing the parent and pass it to the children as context.
var_test = {
"id": 1,
"name": "dad a",
"children_a": [
{
"id": 2,
"name": "child 1 - 2",
"grand_children_a": [
{
"id": 2,
"name": "child 1 - 2",
}
]
},
{
"id": 3,
"name": "child 2 - 2",
}
]
}
class ParentA(Schema):
id = fields.Integer()
name = fields.String()
children_a = fields.Nested('ChildrenA', many=True)
@post_load()
def pl_handler(self, data):
# create Parent A
return data
class ChildrenA(Schema):
id = fields.Integer()
name = fields.String()
grand_children_a = fields.Nested('GrandchildrenA', many=True)
@post_load()
def pl_handler(self, data):
# create child of Parent A
return data
class GrandchildrenA(Schema):
id = fields.Integer()
name = fields.String()
@post_load()
def pl_handler(self, data):
# create child of ChildrenA
return "grand child string"
var_s = ParentA()
var_s.load(var_test)
I think, you don't need post_load, as there is not class which is going to deserialize from this schema, so just remove it, it should work. If you plan to dserialize and hold it to any class, you need to return in post_load decorator, for example :
from marshmallow import Schema, fields, INCLUDE, post_load
class Author:
def __init__(self, name, age):
self.name = name
self.age = age
class Book:
def __init__(self, title, description, author):
self.title = title
self.description = description
self.author = author
class AuthorSchema(Schema):
name = fields.Str()
age = fields.Int()
@post_load
def load_author(self, data, **kwargs):
return Author(**data)
class BookSchema(Schema):
title = fields.Str()
description = fields.Str()
author = fields.Nested(AuthorSchema)
@post_load
def load_book(self, data, **kwargs):
return Book(**data)
data = {
"title": "Test Book",
"description": "A book Test",
"author": {"name": "Vivek", "age": 35},
}
book = BookSchema(unknown=INCLUDE).load(data )
print(book)
print(book.author)
print(book.author.name)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With