Is it possible to validate list using marshmallow?

巧了我就是萌 提交于 2020-01-01 08:25:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!