marshmallow
marshmallow copied to clipboard
Apply an attribute to all fields by default in marshmallow
Is it possible to add an attribute by default to a Marshmallow schema?
For instance, I would like to create a deserialisation only schema. That would imply adding load_only to every field. Find an example below:
class Fruits(Schema)
apple = fields.Str(load_only=True)
banana = fields.Str(load_only=True)
pineapple = fields.Str(load_only=True)
pear = fields.Str(load_only=True)
...
Is that a more elegant way of going about this?
I was able to come up with the following:
class Fruits(Schema)
apple = fields.Str()
banana = fields.Str()
pineapple = fields.Str()
pear = fields.Str()
def __init__(self, **kwargs):
super().__init__(**kwargs)
for field in self.declared_fields.values():
field.load_only = True
Now one could simply isolate that "ugly" attribute setter:
class DeserializerSchema(Schema):
def __init__(self, **kwargs):
super().__init__(**kwargs)
for field in self.declared_fields.values():
field.load_only = True
class Fruits(DeserializerSchema)
...
An alternative way would even use the Meta class (documentation here):
class Fruits(Schema)
apple = fields.Str()
banana = fields.Str()
pineapple = fields.Str()
pear = fields.Str()
class Meta:
load_only = ("apple", "banana", "pineapple", "pear")
I personally don't like much this option since it requires statically adding each field to the list/tuple in the Meta class. Would be nice if there was a selector, like:
class Meta:
load_only = "ALL"
I would like to create a deserialisation only schema
Can you expand on what exactly you think should happen when the schema is serialized? Setting everything to load_only will make the schema silently dump an empty dict. This is something you could implement by extending the schema, and refactor into a decorator for reuse.
class Fruits(Schema)
...
def dump(self, *args, **kwargs):
raise NotImplementedError(...)
def load_only(cls):
def no_dump(*args, **kwargs):
raise NotImplementedError(...)
cls.dump = no_dump
return cls
@load_only
class Fruits(Schema):
...
Is it possible to add an attribute by default to a Marshmallow schema?
Currently there is no way to force all of the fields in a schema to inherit a property from the schema.
I don't see this use case as a strong argument for expanding this API. Rebuilding field instances with additional arguments is messy. See Nested.schema() for an example.
Can you expand on what exactly you think should happen when the schema is serialized?
I haven't really thought about it. But like you said, it silently dumps an empty dict and I guess that's an acceptable behavior. I am quite satisfied with the my __init__ override but your decorator idea is also well thought, perhaps I could merge them both.
I came up with this need and was wondering if there was a native way of achieving this. If any of this will be rolled out in a future release, then I can use the native approach.