Suppose I want to serialize a dict with complex objects, each with their own Schema, like:
class Inner():
a = "testing"
b = "123"
class InnerSchema(Schema):
a = fields.Str()
b = fields.Str()
class Outer():
c = {}
Then populate it, like
o = Outer()
o.c['one'] = Inner()
o.c['two'] = Inner()
What I'd like the serialization to look like is something like:
{
"c": {
"one": {"a": "testing", "b": "123"},
"two": {"a": "testing", "b": "123"}
}
}
What is the schema for class Outer? This gives an error trying to serialize the Inner objects:
class OuterSchema(Schema):
c = fields.Dict(fields.Nested(InnerSchema, many=True))
or, also the same error:
class OuterSchema(Schema):
c = fields.Dict(fields.Nested(InnerSchema), many=True)
Is this possible with fields.Dict in Marshmallow? I have seen things like #424, #120, #258, it seems like it is possible with the new fields.Dict, but here it looks like the Nested is not propagating the Inner schema to the serializer.
TypeError: <__main__.Inner object at 0x7f9673300be0> is not JSON serializable
Thanks!
fields.Dict does not take an inner field as an argument; it does not apply any special formatting on serialization.
However, it would be easy enough to implement:
class ComposableDict(fields.Dict):
def __init__(self, inner, *args, **kwargs):
self.inner = inner
super().__init__(*args, **kwargs)
def _serialize(self, value, attr, obj):
return {
key: self.inner._serialize(val, key, value)
for key, val in value.items()
}
Then use it like so:
class Inner():
a = "testing"
b = "123"
class Outer():
c = {}
class InnerSchema(Schema):
a = fields.Str()
b = fields.Str()
class OuterSchema(Schema):
c = ComposableDict(fields.Nested(InnerSchema))
o = Outer()
o.c['one'] = Inner()
o.c['two'] = Inner()
sch = OuterSchema()
print(sch.dump(o).data)
# {'c': {'one': {'a': 'testing', 'b': '123'}, 'two': {'a': 'testing', 'b': '123'}}}
Thanks! This works perfectly!
Still useful.
In python 2.7: super(fields.Dict, self).__init__(*args, **kwargs)
Note that in Marshmallow 3 (still alpha version as of today), it is possible to specify nested fields for dict keys and values: http://marshmallow.readthedocs.io/en/latest/api_reference.html#marshmallow.fields.Dict.
Right. I just test new implementation from https://github.com/marshmallow-code/apispec/issues/201 and it is much better.
Test with 3.0.0b11 + apispec 0.38
Most helpful comment
fields.Dictdoes not take an inner field as an argument; it does not apply any special formatting on serialization.However, it would be easy enough to implement:
Then use it like so: