Search code examples
pythonserializationmarshmallow

How can I artificially nest schemas in Marshmallow?


In Marshmallow, is there a way to pass the current object to a Nested field in order to produce artificially nested serializations? For example, consider this object that I'm serializing:

example = Example(
    name="Foo",
    address="301 Elm Street",
    city="Kalamazoo",
    state="MI",
)

I want to produce JSON for this that looks like this:

{
    "name": "Foo",
    "address": {
            "street": "301 Elm Street",
            "city": "Kalamazoo",
            "state": "MI"
    }
}

Essentially, this would be a nested AddressSchema inside the ExampleSchema, something like this:

class AddressSchema:
    street = fields.String(attribute="address")
    city = fields.String()
    state = fields.String()

class ExampleSchema:
    name = fields.String()
    address = fields.Nested(AddressSchema)

...but that doesn't quite do what I'd like. I can use a custom function, but I'd like to use a built-in method if possible.


Solution

  • I managed to figure out a solution that allows me to preserve introspection and use only built-in fields; it's a little odd, though. I modified ExampleSchema to include a @pre_dump hook that adds a self-referential attribute, and pointed the field at that:

    class ExampleSchema:
        name = fields.String()
        address = fields.Nested(
            AddressSchema, attribute="_marshmallow_self_reference"
        )
    
        @pre_dump
        def add_self_reference(self, data):
            setattr(data, "_marshmallow_self_reference", data)