Description
If you want to create a field that transforms None
to a preset value, a custom field is required.
Currently the documentation for "Creating A Field Class" states:
To create a custom field class, create a subclass of marshmallow.fields.Field and implement its _serialize and/or _deserialize methods.
https://marshmallow.readthedocs.io/en/latest/custom_fields.html#creating-a-field-class
class Integer(fields.Integer):
def _deserialize(self, value, *args, **kwargs):
value = value or 0
return super()._deserialize(value, *args, **kwargs)
class Test(Schema):
foo = Integer(allow_none=True)
Test().load({'foo': None}) # but it produces {"foo": None} instead of {"foo": 0}
When None
(or missing
) is encountered _deserialize()
is never executed, because Field.deserialize()
returns immediately. The current work around appears to require an understanding of undocumented parts of the Field
implementation and extending deserialize()
instead. The documentation should probably explain the _/de/serialize()
and None/missing interaction.
class Amount(fields.Integer):
def deserialize(self, value, *args, **kwargs):
value = value or 0
return super(Amount, self).deserialize(value, *args, **kwargs)
A similar use case is having a Nested
field supply the default values for the nested schema's fields when the parent field is None
/missing. We may want to explore improving the default behavior in a future version, but for now providing a pattern for this in the docs would be helpful.
class Options(fields.Nested):
def deserialize(self, value, *args, **kwargs):
value = value or {}
return super(Options, self).deserialize(value, *args, **kwargs)
Related to #388