【问题标题】:How to set a lower bound for Int field in marshmallow如何在棉花糖中为 Int 字段设置下限
【发布时间】:2020-08-19 03:21:59
【问题描述】:

是否可以在marshmallow 中为filds.Int 设置下限/上限?

我想做的是

from marshmallow import Schema, fields

class User(Schema):
    age = fields.Int()

u = User()
data = u.load({'age': -1})

>>> data
{'age': 0}

在这种情况下,我想将 0 设置为年龄的下限。

【问题讨论】:

    标签: python marshmallow


    【解决方案1】:

    您似乎无法使用Marshmallow's api 设置一个在反序列化时改变您的输入值的界限;这可能是有充分理由的:看到data = u.load({'age': -1}) 之类的东西并得到{'age': 0} 回来会很混乱。

    您可以做的是将一个函数传递给fields.Intvalidate 参数,它可以让您捕获不需要的值。示例用法:

    class User(Schema):
        age = fields.Int(validate=lambda x: x > 0)  # don't let anything <0 in
    
    
    u = User()
    data = u.load({'age': -1}
    

    输出:

    marshmallow.exceptions.ValidationError: {'age': ['Invalid value.']}
    

    考虑到这些信息,您可以随意处理此异常,例如:

    try:
        data = u.load({'age': -1})
    except marshmallow.exceptions.ValidationError:
        data = u.load({'age': 0})
    

    如果您觉得您必须为您的fields.Int 用法创建一些界限,那么您可以通过以下方式扩展fields.Int

    import typing 
    
    from marshmallow import fields, Schema
    
    _T = typing.TypeVar("_T")
    
    
    class BoundedInt(fields.Int):
        
        def __init__(self, *a, bounds, **kw):
            self._bounds: typing.Tuple[int] = bounds  # bounds=(0, 10)
            super().__init__(*a, **kw)
        
        def _validated(self, value) -> typing.Optional[_T]:
            if value < self._bounds[0]:
                value = self._bounds[0]
            elif value > self._bounds[1]:
                value = self._bounds[1]
            return super()._validated(value)
        
    
    class User(Schema):
        age = BoundedInt(bounds=(0, 10))
    

    用法:

    >>> u = User()
    >>> data = u.load({'age': -1})
    >>> data
    {'age': 0}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-19
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-13
      相关资源
      最近更新 更多