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

FastAPI:让VStatus的Create/Update schema自动生成is_verified且不显示于OpenAPI示例

解决方案:分离请求/响应模型+自动计算字段

问题背景

你有一张VStatus表用于跟踪实体验证状态,当前FastAPI的OpenAPI文档中POST请求体包含is_verified字段,但你希望创建/更新记录时仅传入veri_status和vdesc,is_verified由系统自动计算,同时响应结果中包含该字段,但请求体的OpenAPI示例不显示它。

具体实现步骤

1. 重构模型结构,分离请求与响应字段

将核心请求字段(veri_status、vdesc)与包含自动计算字段的数据库/响应模型分离,避免is_verified出现在请求schema中:

from sqlmodel import SQLModel, Field, Column, String, Boolean
from uuid import UUID
from enum import Enum
from sqlalchemy import case

class VerificationStatusEnum(Enum):
    Unverified = "Unverified"
    Verified = "Verified"
    Pending = "Pending"

# 仅包含请求所需的核心字段,用于Create/Update请求模型
class VStatusCore(SQLModel):
    veri_status: VerificationStatusEnum = Field(
        default=VerificationStatusEnum.Unverified, nullable=False)
    vdesc: str = Field(default='', sa_column=Column("vdesc", String))

# 数据库实体模型,包含自动计算的is_verified
class VStatus(VStatusCore, table=True):
    id: UUID = Field(default=None, primary_key=True)
    # 数据库层面自动计算is_verified:当veri_status为Verified时设为True,否则False
    is_verified: bool = Field(
        sa_column=Column(
            Boolean,
            server_default=case(
                (veri_status == VerificationStatusEnum.Verified, True),
                else_=False
            ),
            server_onupdate=case(
                (veri_status == VerificationStatusEnum.Verified, True),
                else_=False
            )
        )
    )

# Create请求模型:仅继承核心字段,OpenAPI文档不会显示is_verified
class IVStatusCreate(VStatusCore):
    pass

# Read响应模型:包含所有字段(包括自动生成的is_verified)
class IVStatusRead(VStatusCore):
    id: UUID
    is_verified: bool

# 简洁版响应模型
class IVStatusConciseRead(SQLModel):
    veri_status: VerificationStatusEnum
    is_verified: bool

# Update请求模型:同样仅继承核心字段,更新时自动同步is_verified
@optional
class IVStatusUpdate(VStatusCore):
    pass

2. 自动计算is_verified的两种方式

  • 数据库层面自动计算(推荐):
    上述代码通过SQLAlchemy的case表达式实现了server_default和server_onupdate逻辑,当插入或更新veri_status时,数据库会自动计算并设置is_verified的值,无需在业务代码中额外处理。

  • 业务代码中计算:
    如果不想依赖数据库计算逻辑,可以在FastAPI端点中手动计算:

    from fastapi import FastAPI, Depends, HTTPException
    from sqlmodel import Session, create_engine
    
    app = FastAPI()
    engine = create_engine("sqlite:///test.db")
    
    def get_session():
        with Session(engine) as session:
            yield session
    
    @app.post("/vstatus/", response_model=IVStatusRead)
    def create_vstatus(vstatus_data: IVStatusCreate, session: Session = Depends(get_session)):
        # 根据veri_status计算is_verified
        is_verified = vstatus_data.veri_status == VerificationStatusEnum.Verified
        # 创建数据库实例并传入计算后的值
        db_vstatus = VStatus(**vstatus_data.dict(), is_verified=is_verified)
        session.add(db_vstatus)
        session.commit()
        session.refresh(db_vstatus)
        return db_vstatus
    
    @app.patch("/vstatus/{vstatus_id}", response_model=IVStatusRead)
    def update_vstatus(vstatus_id: UUID, vstatus_data: IVStatusUpdate, session: Session = Depends(get_session)):
        db_vstatus = session.get(VStatus, vstatus_id)
        if not db_vstatus:
            raise HTTPException(status_code=404, detail="VStatus not found")
        # 更新核心字段
        update_data = vstatus_data.dict(exclude_unset=True)
        for key, value in update_data.items():
            setattr(db_vstatus, key, value)
        # 重新计算is_verified
        db_vstatus.is_verified = db_vstatus.veri_status == VerificationStatusEnum.Verified
        session.commit()
        session.refresh(db_vstatus)
        return db_vstatus
    

3. 验证效果

此时,Create和Update的请求体示例将只显示veri_status和vdesc,而响应示例会包含is_verified字段,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:25:16