Pydantic在响应模型中使用“Union”和“Field”时无法序列化/验证

2024-09-28 22:10:42 发布

您现在位置:Python中文网/ 问答频道 /正文

  • 操作系统:Ubuntu 18.04.4 LTS
  • Python版本:3.7.7
  • Pydantic版本:1.4

我试图将class TableSetting设为BaseModel,并将其设为response body。但是这个类中似乎有一些验证或序列化错误。 我想可能是UnionOptional[str]我使用了,但不确定

源代码

from fastapi import FastAPI, Query, Body, Path
from pydantic import BaseModel, Field
from typing import Union, Optional
from enum import Enum


app = FastAPI()


class Tableware(str, Enum):
    SPOON= "SPOON"
    FORK= "FORK"

class TableSetting(BaseModel):
    kitchen: Union[Tableware, Optional[str]] = Field(..., title="I am title")
    numberOfknife: int = Field(None, ge=0, le=4)

@app.post(
    "/{tableNumber}/provide-table-setting",
    response_model= TableSetting,    
)

def provide_table_setting(
    *,
    tableNumber: str= Path(...),
):
    results = {"tableNumber": tableNumber}
    return results

class TableSetting的json模式应该如下所示

TableSetting{
    kitchen*        I am title{
                        anyOf ->    string  
                                    Enum:
                                        [ SPOON, FORK ]
                                    string
                    }
    numberOfknife   integer
                    maximum: 4
                    minimum: 0
}

在执行curl

curl -X POST "http://localhost:8000/2/provide-table-setting" -H  "accept: application/json"

它返回的错误如下:响应代码500,内部服务器错误,似乎有些kitchen存在一些验证问题,但我不知道为什么

INFO:     127.0.0.1:53558 - "POST /2/provide-table-setting HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/*****/miniconda3/envs/fastAPI/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
    result = await app(self.scope, self.receive, self.send)
.
.
.
  File "/home/*****/miniconda3/envs/fastAPI/lib/python3.7/site-packages/fastapi/routing.py", line 126, in serialize_response
    raise ValidationError(errors, field.type_)
pydantic.error_wrappers.ValidationError: 1 validation error for TableSetting
response -> kitchen
  field required (type=value_error.missing)

但是,当从代码中删除= Field(..., title="I a title")时,如下所示。它可以使用响应代码200,但是因为我需要Item kitchen,所以这不是我想要的

class TableSetting(BaseModel):
    kitchen: Union[Tableware, Optional[str]]
    numberOfknife: int = Field(None, ge=0, le=4)

我怎样才能解决这个问题

谢谢


Tags: fromimportfieldtitleresponsetableoptionalclass
1条回答
网友
1楼 · 发布于 2024-09-28 22:10:42

根据docUnion它接受不同的类型,但不是两者都接受, 与此相反,您应该使用tuple with(必选,可选) 诸如此类

from typing import Optional, Tuple
class TableSetting(BaseModel):
    kitchen: Tuple[Tableware, Optional[str]] = (None, Field(..., title="I am title"))
    #kitchen: Union[Tableware, Optional[str]] 
    numberOfknife: int = Field(None, ge=0, le=4)

相关问题 更多 >