如何使用marshmallow校验功能验证列表内所有元素的唯一性?
Marshmallow列表元素唯一性校验实现方案
可以实现需求,以下是两种常用实现方式:
方案1:复用型自定义校验器
适合需要在多个Schema的List字段复用唯一校验逻辑的场景:
- 先定义通用的列表元素唯一性校验函数
from marshmallow import Schema, fields, validate, ValidationError def validate_unique_list(value): if len(value) != len(set(value)): raise ValidationError("列表中不允许存在重复元素")
- 将校验器挂载到
currencies对应的List字段的validate参数上(注意是加在List层级,不是内部的String字段层级)
修改后的Schema代码如下:
class PaymentSchema(Schema): currencies = fields.List( fields.String( required=True, validate=[ validate.OneOf(["USD", "EUR", "AUS", "GBP"]), validate.Length(min=1, max=4) ] ), validate=validate_unique_list )
方案2:Schema专属校验装饰器
适合仅当前Schema需要该校验逻辑,无需复用的场景:
通过marshmallow提供的@validates装饰器绑定字段校验规则,还可以优化错误提示,直接定位重复元素:
from marshmallow import Schema, fields, validate, validates, ValidationError from collections import Counter class PaymentSchema(Schema): currencies = fields.List( fields.String( required=True, validate=[ validate.OneOf(["USD", "EUR", "AUS", "GBP"]), validate.Length(min=1, max=4) ] ) ) @validates("currencies") def validate_currencies_unique(self, value): counter = Counter(value) duplicates = [item for item, cnt in counter.items() if cnt > 1] if duplicates: raise ValidationError(f"货币列表存在重复项:{', '.join(duplicates)}")
两种方案测试传入["USD", "EUR", "EUR"]时,都会触发ValidationError抛出,符合需求。
内容的提问来源于stack exchange,提问作者jcunhafonte
相关产品推荐
相关产品推荐

