如何通过类变量修改FastAPI所用Pydantic模型的Field参数?
问题解决与方案说明
根因分析
原代码校验不生效的核心原因是:Field()的入参在类定义阶段就完成解析赋值,定义User1类时,ge=_set_ge已经读取了当时_set_ge的初始值None写入校验规则,后续修改类属性_set_ge不会回溯更新已经生成的Field配置,因此校验逻辑不会触发。
适配FastAPI场景的实现方案
以下两种方案都可以在不大量重复代码的前提下实现动态调整字段校验规则的需求,且完全兼容FastAPI的参数解析、校验和OpenAPI文档生成逻辑。
方案1:模型工厂函数(更推荐)
通过工厂函数按需生成不同校验规则的模型类,代码复用性最高,无需处理继承相关的兼容问题:
from pydantic import BaseModel, Field from fastapi import FastAPI # 模型工厂:公共字段统一在内部定义,仅通过入参暴露需要调整的校验参数 def create_user_model(item_ge: float | None = None) -> type[BaseModel]: class User(BaseModel): # 所有公共字段、公共校验逻辑都可以放在这里统一维护 item: float = Field(..., ge=item_ge) # 可扩展其他公共字段 return User # 按需生成不同校验规则的模型 User1 = create_user_model() # 无ge校验 NewUser1 = create_user_model(item_ge=0) # 校验item >= 0 app = FastAPI() @app.post("/") def endpoint(request: NewUser1): return request.item
方案2:类继承+动态校验器
如果必须使用类继承的写法,可以通过自定义字段校验器在运行时读取类属性做校验:
from pydantic import BaseModel, Field, field_validator class User1(BaseModel): _set_ge: float | None = None item: float = Field(...) @field_validator("item") @classmethod def check_item_ge(cls, v: float) -> float: if cls._set_ge is not None and v < cls._set_ge: raise ValueError(f"item must be greater than or equal to {cls._set_ge}") return v # 继承后仅需修改类属性即可调整校验规则 class NewUser1(User1): _set_ge = 0
注意事项
原示例代码存在两处拼写错误会导致运行报错:
Basemodel需修改为BaseModel(首字母M大写)Fastapi需修改为FastAPI(首字母A、P大写)
内容的提问来源于stack exchange,提问作者Svencken
相关产品推荐
相关产品推荐

