如何在FastAPI接收Request后动态生成SQLModel新字段?
在FastAPI中基于请求字段自动生成新字段并插入数据库
问题说明
需要在FastAPI接收请求后,基于现有字段(如name)自动生成repr_name字段(通过python-slugify处理为下划线分隔格式),最终将包含新字段的数据插入数据库。之前尝试的default_factory无法引用实例字段,且误以为SQLModel不支持__post_init__方法,导致实现失败。
错误原因分析
default_factory的误区:原代码中functools.partial(slugify, name, separator='_')里的name是类属性,并非实例化后的self.name,无法动态获取请求传入的name值。__post_init__的误解:SQLModel继承自Pydantic的BaseModel,完全支持__post_init__实例初始化钩子,之前的问题是写法错误而非不支持。
正确实现方案
方案一:使用__post_init__钩子
import functools from datetime import date, datetime from slugify import slugify from sqlmodel import Field, SQLModel class ProjectBase(SQLModel): is_active: bool = Field(default=True, nullable=False) name: str = Field(..., nullable=False) # 修正default_factory写法,用lambda延迟执行日期生成 publish_date: date = Field(default_factory=lambda: datetime.now().date(), nullable=False) repr_name: str = Field(..., description="项目的标准化名称,无空格,以下划线分隔,由python-slugify生成", nullable=False) def __post_init__(self): # 初始化后自动用name生成repr_name self.repr_name = slugify(self.name, separator='_')
方案二:使用Pydantic字段验证器
如果需要支持手动传入repr_name(未传入时自动生成),可以用field_validator实现:
import functools from datetime import date, datetime from slugify import slugify from sqlmodel import Field, SQLModel from pydantic import field_validator class ProjectBase(SQLModel): is_active: bool = Field(default=True, nullable=False) name: str = Field(..., nullable=False) publish_date: date = Field(default_factory=lambda: datetime.now().date(), nullable=False) repr_name: str = Field(None, description="项目的标准化名称,无空格,以下划线分隔,由python-slugify生成", nullable=False) @field_validator('repr_name', mode='before') def generate_repr_name(cls, value, values): # 若未传入repr_name,用name字段生成 if value is None: return slugify(values.get('name'), separator='_') return value
效果验证
当传入如下请求:
{ "is_active": true, "name": "hello world bye", "publish_date": "2023-01-01" }
会自动生成并输出包含repr_name的结果,符合预期:
{ "is_active": true, "name": "hello world bye", "repr_name": "hello_world_bye", "publish_date": "2023-01-01" }
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

