0

I am trying to serialize an object with Marshmallow in such a way that "related" properties are grouped together into a single dictionary that does not exist on the original object. My code:

from marshmallow import Schema, fields, pprint
import json

class StatsSchema(Schema):
    population = fields.Int()
    rating = fields.Int()

class AnimalSchema(Schema):
    name = fields.Str()
    features = fields.List(fields.Str())
    stats = fields.Nested(StatsSchema)

dog = {
    'name':'dog',
    'features': ['tongue', 'wet nose'],
    'population': 200,
    'rating': 10
}

animal_schema = AnimalSchema()
data, errors = animal_schema.dump(dog)

print(json.dumps(data, indent=2))

Actual result:

{
  "features": [
    "tongue",
    "wet nose"
  ],
  "name": "dog"
}

Desired result:

{
  "features": [
    "tongue",
    "wet nose"
  ],
  "name": "dog",
  "stats": {"population": 500, "rating": 10}
}

I understand that the "stats" key is missing from the output because it is not on the original object, but I am not sure how to specify that Marshmallow should create the new "stats" key as a new dictionary using the object.

wbruntra
  • 1,021
  • 1
  • 10
  • 18

2 Answers2

1

I found one possible way to create the inner dictionary. Not sure if it is the only/best method:

class AnimalSchema(Schema):
    name = fields.Str()
    features = fields.List(fields.Str())
    stats = fields.Method('get_stats')

    def get_stats(self, post):
        data, err = StatsSchema().dump(post)
        return data
wbruntra
  • 1,021
  • 1
  • 10
  • 18
0

This is discussed in https://github.com/marshmallow-code/marshmallow/issues/940.

You could do that

class AnimalSchema(Schema):
    name = fields.Str()
    features = fields.List(fields.Str())
    stats = fields.Nested(StatsSchema, dump_only=True)

class Animal:
    [...]
    @property
    def stats(self):
        return {'population': self.population, 'rating': self.rating}
Jérôme
  • 13,328
  • 7
  • 56
  • 106