You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cerberus中校验数字长度?ISBN字段需支持10或13位

解决Cerberus中ISBN字段的10/13位数字验证问题

嘿,我之前在Cerberus里处理ISBN验证时也踩过这个坑!你遇到的问题其实是因为Cerberus的maxlength/minlength只对字符串类型生效,数字/整数类型根本不吃这套规则。给你两个实用的解决方案:

方案1:用正则+anyof适配不同类型

如果你的ISBN既可能是字符串格式(比如带引号的数字)也可能是整数,我们可以用anyof分别针对两种类型设置规则:

from cerberus import Validator

book_schema = {
    "isbn": {
        "anyof": [
            # 匹配10或13位的数字字符串
            {
                "type": "string",
                "regex": r"^\d{10}$|^\d{13}$"
            },
            # 匹配10或13位的整数
            {
                "type": "integer",
                # 用数值范围锁定位数:10位最小是1000000000,13位最大是9999999999999
                "min": 1000000000,
                "max": 9999999999999,
                # 再通过anyof区分10位和13位的数值区间
                "anyof": [
                    {"max": 9999999999},    # 10位整数的最大值
                    {"min": 1000000000000}  # 13位整数的最小值
                ]
            }
        ]
    }
}

# 测试验证效果
v = Validator(book_schema)
print(v.validate({"isbn": "9781234567890"}))  # 13位字符串 → True
print(v.validate({"isbn": 1234567890}))       # 10位整数 → True
print(v.validate({"isbn": "123456789"}))      # 9位字符串 → False
print(v.validate({"isbn": 123456789}))        # 9位整数 → False

方案2:自定义验证规则(更简洁灵活)

如果觉得上面的写法太啰嗦,直接自定义一个验证函数,不管输入是字符串还是数字,统一转成字符串判断长度和是否为纯数字:

from cerberus import Validator

# 自定义ISBN验证函数
def check_isbn_valid(field, value, error):
    isbn_str = str(value)
    # 检查长度是10或13,且全为数字
    if len(isbn_str) not in (10, 13) or not isbn_str.isdigit():
        error(field, "ISBN必须是10位或13位的纯数字")

# 注册自定义验证器
v = Validator()
v.add_validator("isbn_valid", check_isbn_valid)

# 编写Schema
book_schema = {
    "isbn": {
        "type": ["string", "integer"],  # 允许字符串或整数类型
        "isbn_valid": True              # 启用自定义验证规则
    }
}

v.schema = book_schema
# 测试验证效果
print(v.validate({"isbn": "9780306406157"}))  # 13位字符串 → True
print(v.validate({"isbn": 9780306406157}))     # 13位整数 → True
print(v.validate({"isbn": "abc123456789"}))    # 含非数字字符 → False
print(v.validate({"isbn": 123456789}))         # 9位整数 → False

简单总结一下:Cerberus的maxlength/minlength是字符串专属规则,数字类型得用数值范围或者自定义函数来约束长度。第二种方案更推荐,因为代码更简洁,扩展性也更强(比如后续可以加ISBN的校验位验证)。

内容的提问来源于stack exchange,提问作者Nerldy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:39:53