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

FastAPI/Pydantic返回ACK时提示字段缺失,请求排查解决

FastAPI Pydantic 响应验证错误解决案例

问题背景

定义的Pydantic模型

from pydantic import BaseModel, Optional
from your_module import settings

class BaseMessage(BaseModel):
    """
    ACK/NACK响应的基础模型
    """
    origin: str = settings.APP_ORIGIN_NAME
    message: str

class Success(BaseMessage):
    """
    成功响应的API模型
    """
    id: str
    temp_password: Optional[str] | None

class ACK(BaseModel):
    """
    ACK响应的API模型
    """
    ACK: Success

POST端点实现代码

from fastapi import APIRouter, status, JSONResponse
from pydantic import ValidationError
from typing import Union
import asyncpg
from your_module import Domains, DomainCreate, ENDPOINT_MESSAGES, APIResponse, get_password_hash

router = APIRouter()

@router.post(
    path="/",
    summary="注册新域名",
    description="注册一个新域名。",
    response_model=Union[ACK, NACK],
    name="domains:create-domain",
    status_code=status.HTTP_201_CREATED,
    responses={400: {"model": NACK}},
)
async def create_domain(
    domain: DomainCreate, 
) -> JSONResponse:
    try:
        instance = Domains(**domain.dict(exclude_unset=True))
        instance.domain_hashed_password = get_password_hash(
            instance.domain_hashed_password
        )
        db_instance = await Domains(**instance.dict(exclude_unset=True)).save()

        domain_id: str = str(db_instance.domain_id)

        success_text: str = ENDPOINT_MESSAGES["success"]
        
        try:
            ack_message = ACK(
                message=success_text,
                id=domain_id,
                temp_password=instance.domain_hashed_password,
            )

            return JSONResponse(
                status_code=status.HTTP_201_CREATED,
                content=jsonable_encoder(ack_message),
            )
        except ValidationError as exc:
            print(exc.errors())
    except asyncpg.exceptions.UniqueViolationError:
        failure_text: str = ENDPOINT_MESSAGES["failure"]
        error_text: str = f"{ENDPOINT_MESSAGES['err_unique']} domain_name"
        nack_message: dict = APIResponse.nack(failure_text, error_text)

        return JSONResponse(
            status_code=status.HTTP_400_BAD_REQUEST, content=nack_message
        )

报错信息

向该端点发送POST请求时,持续收到以下错误:

ACK
  field required (type=value_error.missing)

fastapi.exceptions.ResponseValidationError: 1 validation errors:
  {'loc': ('response',), 'msg': 'none is not an allowed value', 'type': 'type_error.none.not_allowed'}

错误发生在ack_message实例化环节,但用户认为已提供所有必要字段,期望返回的响应格式为:

{
  "ACK": {
    "origin": "APP_ORIGIN_NAME的内容",
    "message": "success_text的内容",
    "id": "domain_id的内容",
    "temp_password": "domain_hashed_password的内容"
  }
}

解决方案

已解决:根据Victor的回答,将ack_message的定义修改为:

ack_message = ACKResponse(
    ACK={
        "message": success_text,
        "id": domain_id,
        "temp_password": unhashed_password,
    }
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:28:26