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

如何在FastAPI接收Request后动态生成SQLModel新字段?

在FastAPI中基于请求字段自动生成新字段并插入数据库

问题说明

需要在FastAPI接收请求后,基于现有字段(如name)自动生成repr_name字段(通过python-slugify处理为下划线分隔格式),最终将包含新字段的数据插入数据库。之前尝试的default_factory无法引用实例字段,且误以为SQLModel不支持__post_init__方法,导致实现失败。

错误原因分析

  1. default_factory的误区:原代码中functools.partial(slugify, name, separator='_')里的name是类属性,并非实例化后的self.name,无法动态获取请求传入的name值。
  2. __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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:25:30