marshmallow-polyfield

5.11 · active · verified Thu Apr 16

marshmallow-polyfield is an unofficial extension to Marshmallow (version 3+) that enables defining polymorphic fields within your schemas. It allows for serialization and deserialization of objects that can have different underlying types, mapping them to appropriate Marshmallow schemas based on a discriminator field. The current version is 5.11, and it maintains an active release cadence to ensure compatibility with recent Marshmallow versions.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `PolyField` to handle polymorphic objects. It defines `Dog` and `Cat` classes with corresponding `DogSchema` and `CatSchema`. The `AnimalSchema` then uses `PolyField` with `deserialization_schema_map`, `serialization_schema_map`, and a `lookup_field` to correctly map between object types and schemas during both serialization and deserialization. The `lookup_field` ('animal_type' in this case) is crucial for `marshmallow-polyfield` to determine which concrete schema to use.

from marshmallow import Schema, fields
from marshmallow_polyfield import PolyField

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
        self.animal_type = 'dog'

class Cat:
    def __init__(self, name, color):
        self.name = name
        self.color = color
        self.animal_type = 'cat'

class DogSchema(Schema):
    name = fields.String(required=True)
    breed = fields.String(required=True)
    animal_type = fields.Constant('dog')

class CatSchema(Schema):
    name = fields.String(required=True)
    color = fields.String(required=True)
    animal_type = fields.Constant('cat')

class AnimalSchema(Schema):
    animal = PolyField(
        deserialization_schema_map={
            'dog': DogSchema,
            'cat': CatSchema
        },
        serialization_schema_map={
            'dog': DogSchema,
            'cat': CatSchema
        },
        lookup_field='animal_type'
    )

# --- Example Usage ---
dog_obj = Dog(name='Buddy', breed='Golden Retriever')
cat_obj = Cat(name='Whiskers', color='black')

# Serialization
poly_schema = AnimalSchema()
dog_data = poly_schema.dump({'animal': dog_obj})
cat_data = poly_schema.dump({'animal': cat_obj})

print(f"Serialized Dog: {dog_data}")
print(f"Serialized Cat: {cat_data}")

# Deserialization
dog_dict = {'animal_type': 'dog', 'name': 'Rex', 'breed': 'German Shepherd'}
cat_dict = {'animal_type': 'cat', 'name': 'Mittens', 'color': 'white'}

deserialized_dog = poly_schema.load({'animal': dog_dict})
deserialized_cat = poly_schema.load({'animal': cat_dict})

print(f"Deserialized Dog type: {type(deserialized_dog['animal'])}")
print(f"Deserialized Cat type: {type(deserialized_cat['animal'])}")

view raw JSON →