{"id":9096,"library":"marshmallow-polyfield","title":"marshmallow-polyfield","description":"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.","status":"active","version":"5.11","language":"en","source_language":"en","source_url":"https://github.com/Bachmann1234/marshmallow-polyfield","tags":["marshmallow","serialization","deserialization","polymorphism","rest","api","schema"],"install":[{"cmd":"pip install marshmallow-polyfield","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency; this library extends Marshmallow's functionality.","package":"marshmallow","optional":false}],"imports":[{"symbol":"PolyField","correct":"from marshmallow_polyfield import PolyField"},{"note":"Less commonly used for simple polymorphic fields; PolyField is more direct.","symbol":"PolySchema","correct":"from marshmallow_polyfield import PolySchema"}],"quickstart":{"code":"from marshmallow import Schema, fields\nfrom marshmallow_polyfield import PolyField\n\nclass Dog:\n    def __init__(self, name, breed):\n        self.name = name\n        self.breed = breed\n        self.animal_type = 'dog'\n\nclass Cat:\n    def __init__(self, name, color):\n        self.name = name\n        self.color = color\n        self.animal_type = 'cat'\n\nclass DogSchema(Schema):\n    name = fields.String(required=True)\n    breed = fields.String(required=True)\n    animal_type = fields.Constant('dog')\n\nclass CatSchema(Schema):\n    name = fields.String(required=True)\n    color = fields.String(required=True)\n    animal_type = fields.Constant('cat')\n\nclass AnimalSchema(Schema):\n    animal = PolyField(\n        deserialization_schema_map={\n            'dog': DogSchema,\n            'cat': CatSchema\n        },\n        serialization_schema_map={\n            'dog': DogSchema,\n            'cat': CatSchema\n        },\n        lookup_field='animal_type'\n    )\n\n# --- Example Usage ---\ndog_obj = Dog(name='Buddy', breed='Golden Retriever')\ncat_obj = Cat(name='Whiskers', color='black')\n\n# Serialization\npoly_schema = AnimalSchema()\ndog_data = poly_schema.dump({'animal': dog_obj})\ncat_data = poly_schema.dump({'animal': cat_obj})\n\nprint(f\"Serialized Dog: {dog_data}\")\nprint(f\"Serialized Cat: {cat_data}\")\n\n# Deserialization\ndog_dict = {'animal_type': 'dog', 'name': 'Rex', 'breed': 'German Shepherd'}\ncat_dict = {'animal_type': 'cat', 'name': 'Mittens', 'color': 'white'}\n\ndeserialized_dog = poly_schema.load({'animal': dog_dict})\ndeserialized_cat = poly_schema.load({'animal': cat_dict})\n\nprint(f\"Deserialized Dog type: {type(deserialized_dog['animal'])}\")\nprint(f\"Deserialized Cat type: {type(deserialized_cat['animal'])}\")\n","lang":"python","description":"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."},"warnings":[{"fix":"Ensure your project explicitly installs `marshmallow>=3.0.0`. If migrating an existing Marshmallow 2.x project, consult Marshmallow's official migration guide first.","message":"marshmallow-polyfield requires Marshmallow 3.x. Using it with Marshmallow 2.x will lead to various AttributeErrors or unexpected behavior due to significant API changes between Marshmallow major versions.","severity":"breaking","affected_versions":"< 5.7"},{"fix":"Double-check that the string value returned by `lookup_field` (or present in your input data) precisely matches one of the keys in `deserialization_schema_map` and `serialization_schema_map`.","message":"Incorrectly configured `lookup_field` or `schema_map` can lead to `KeyError` during deserialization or `ValidationError`. The `lookup_field` value in the data must exactly match a key in your `deserialization_schema_map`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always provide both `deserialization_schema_map` and `serialization_schema_map` to `PolyField` for complete functionality. Ensure the keys and values align with your expected object types and schemas.","message":"`marshmallow-polyfield` does not automatically infer the type for serialization. Both `deserialization_schema_map` and `serialization_schema_map` must be provided and correctly configured for bidirectional polymorphism.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Upgrade your `marshmallow` dependency to version 3.x or higher: `pip install --upgrade marshmallow`","cause":"This error often indicates that you are running `marshmallow-polyfield` (which targets Marshmallow 3) with an older version of `marshmallow` (e.g., 2.x).","error":"AttributeError: 'Field' object has no attribute '_declared_fields'"},{"fix":"Verify that the `lookup_field` name in your `PolyField` definition matches the key in your input data, and that its value corresponds to a key in `deserialization_schema_map`.","cause":"This usually occurs during deserialization when the value of the `lookup_field` in the input data does not match any of the keys defined in your `deserialization_schema_map`.","error":"KeyError: 'type_field_value'"},{"fix":"Add the `lookup_field` argument to your `PolyField` instantiation, specifying the name of the field that determines the object's type (e.g., `lookup_field='object_type'`).","cause":"You've attempted to initialize `PolyField` without providing the mandatory `lookup_field` argument, which tells it which field to use for type discrimination.","error":"TypeError: __init__() missing 1 required positional argument: 'lookup_field'"}]}