问题
Is it possible to validate list using marshmallow?
class SimpleListInput(Schema):
items = fields.List(fields.String(), required=True)
# expected invalid type error
data, errors = SimpleListInput().load({'some': 'value'})
# should be ok
data, errors = SimpleListInput().load(['some', 'value'])
Or it is expected to validate only objects?
回答1:
To validate top-level lists, you need to instantiate your list item schema with many=True
argument.
Example:
class UserSchema(marshmallow.Schema):
name = marshmallow.fields.String()
data, errors = UserSchema(many=True).load([
{'name': 'John Doe'},
{'name': 'Jane Doe'}
])
But it still needs to be an object schema, Marshmallow does not support using top-level non-object lists. In case you need to validate top-level list of non-object types, a workaround would be to define a schema with one List field of your types and just wrap payload as if it was an object:
class SimpleListInput(marshmallow.Schema):
items = marshmallow.fields.List(marshmallow.fields.String(), required=True)
payload = ['foo', 'bar']
data, errors = SimpleListInput().load({'items': payload})
回答2:
SimpleListInput is a class with a property "items". The property "items" is who accepts a list of strings.
>>> data, errors = SimpleListInput().load({'items':['some', 'value']})
>>> print data, errors
{'items': [u'some', u'value']}
{}
>>> data, errors = SimpleListInput().load({'items':[]})
>>> print data, errors
{'items': []}
{}
>>> data, errors = SimpleListInput().load({})
>>> print data, errors
{}
{'items': [u'Missing data for required field.']}
If you want a custom validate, for example, not accept an empty list in "items":
from marshmallow import fields, Schema, validates, ValidationError
class SimpleListInput(Schema):
items = fields.List(fields.String(), required=True)
@validates('items')
def validate_length(self, value):
if len(value) < 1:
raise ValidationError('Quantity must be greater than 0.')
Then...
>>> data, errors = SimpleListInput().load({'items':[]})
>>> print data, errors
{'items': []}
{'items': ['Quantity must be greater than 0.']}
Take a look at Validation
UPDATE:
As the Turn comment below. You can do this:
from marshmallow import fields, Schema, validate
class SimpleListInput(Schema):
items = fields.List(fields.String(), required=True, validates=validate.Length(min=1))
回答3:
Please take a look at a little library written by me which tries to solve exactly this problem: https://github.com/and-semakin/marshmallow-toplevel.
Installation:
pip install marshmallow-toplevel
Usage (on the example from Maxim Kulkin):
import marshmallow
from marshmallow_toplevel import TopLevelSchema
class SimpleListInput(TopLevelSchema):
_toplevel = marshmallow.fields.List(
marshmallow.fields.String(),
required=True,
validate=marshmallow.validate.Length(1, 10)
)
# raises ValidationError, because:
# Length must be between 1 and 10.
SimpleListInput().load([])
# raises ValidationError, because:
# Length must be between 1 and 10.
SimpleListInput().load(["qwe" for _ in range(11)])
# successfully loads data
payload = ["foo", "bar"]
data = SimpleListInput().load(payload)
assert data == ["foo", "bar"]
Of course it can be used with more complex schemas than just string in example.
来源:https://stackoverflow.com/questions/37237350/is-it-possible-to-validate-list-using-marshmallow