When I have something like this:
from marshmallow import Schema, fields
class UserSchema(Schema):
name = fields.Str(required=True)
email = fields.Email(required=True)
created_at = fields.DateTime()
some_other = fields.Str(default='This is something else')
user_data = {
'created_at': '2014-08-11T05:26:03.869245',
'email': u'[email protected]',
'name': u'Ken'
}
schema = UserSchema()
result = schema.load(user_data)
pprint(result)
I currently get:
{'created_at': datetime.datetime(2014, 8, 11, 5, 26, 3, 869245),
'email': '[email protected]',
'name': 'Ken'}
I would expect that some_other would be added with the default set to This is something else, especially if we are passing this to @post_load to create an object so that I don't have to have said object also handle setting the default (and potentially getting out of sync).
This is especially handy when using marshmallow to validate and transform the data as necessary on a load before passing it further down the stack to avoid having to add a bunch of if key in obj statements.
Currently I end up doing:
result = schema.dump(schema.load(user_data))
pprint(result)
Which does have the desired result:
{'created_at': '2014-08-11T05:26:03.869245+00:00',
'email': '[email protected]',
'name': 'Ken',
'some_other': 'This is something else'}
but is doing a lot of extra work that shouldn't be necessary.
Is there already a recipe for doing something like this with a @post_load decorator? If so I don't mind using that.
If only I had the nagging feeling to check the docs for Field before I opened this issue and found missing.
Sorry for the noise!
It does seem arbitrary for default to only be used for serialization. It isn't immediately obvious that missing is the deserialization complement. It would be nice if there was a little more symmetry here. Maybe something like default_load, default_dump, and default to set both at once.
@deckar01 this sounds reasonable. Would you like to open a RFC to discuss this for marshmallow 3?
I've used both missing and default but it doesn't add the field. What am I missing?
Using:
marshmallow==3.0.0b8
marshmallow-enum==1.4.1
marshmallow-sqlalchemy==0.13.2
I've used both missing and default but it doesn't add the field. What am I missing?
Using:
marshmallow==3.0.0b8
marshmallow-enum==1.4.1
marshmallow-sqlalchemy==0.13.2
Do something like this;
from marshmallow import Schema, fields, pre_load
from random import randint
from uuid import uuid4
class Testing(Schema):
user_id = fields.Integer(missing=randint(1, 100), allow_none=True)
name = fields.String(missing=str(uuid4()), allow_none=True)
@pre_load
def delete_none_values(self, in_data, **kwargs):
"""Delete all None values so they get filled out with their 'missing' parameters."""
to_delete = []
for key, value in in_data.items():
if value is None:
# can't delete dict values on the fly, it produces an error
to_delete.append(key)
for key in to_delete:
del in_data[key]
return in_data
Testing().load(dict(name=None))
Most helpful comment
It does seem arbitrary for
defaultto only be used for serialization. It isn't immediately obvious thatmissingis the deserialization complement. It would be nice if there was a little more symmetry here. Maybe something likedefault_load,default_dump, anddefaultto set both at once.