FastApi 当response_model=union[ModeA,ModeB]时,返回数据仅转化为ModeA形式问题

接口需求:根据构造的返回数据字典,自动正确适配Union中的数据模型


问题引出:运行如下代码,期待输出为:当请求中的id值为1时,按照DataA模型定义的格式返回结果,当id值为2时,按照DataB模型定义的格式返回结果,

                                        但实际结果为:当请求中的id值为1时,按照DataA模型定义的格式返回结果,当id值为2时,按照DataA模型定义的格式返回结果

import uvicorn

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Union

app = FastAPI()


class DataA(BaseModel):
    name: str = 'newa'   
    age: int = 10


class DataB(BaseModel):
    user: str = 'tom'
    passward: str = '0'


@app.get("/test/{id}", response_model=Union[DataA, DataB])
async def update_item(id: int):
    if id == 1:
        return {'name': 'da', 'age': 20}
    if id == 2:
        return {'user': 'alice', 'passward': '123456'}


if __name__ == '__main__':
    uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)

实际运行结果为:

请求URL:http://127.0.0.1:8004/test/1,返回结果:

{
  "name": "da",
  "age": 20
}

请求URL:http://127.0.0.1:8004/test/2,返回结果:

{
  "name": "newa",
  "age": 10
}

原因分析:DataA和DataB中的所有字段均定义了默认值,所以虽然返回的是DataB形式的数据,但程序仍认为数据的类型为Union中设置的第一个数据类型DataA,故返回结果产生错误


解决方案:在DataA和DataB中设置一个区分彼此的字段,字段设置为 必填且没有默认值,具体来说,就是将上述代码改动如下:

import uvicorn

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Union

app = FastAPI()


class DataA(BaseModel):
    name: str     #区分字段,必填且没有默认值
    age: int = 10


class DataB(BaseModel):
    user: str     #区分字段,必填且没有默认值
    passward: str = '0'


@app.get("/test/{id}", response_model=Union[DataA, DataB])
async def update_item(id: int):
    if id == 1:
        return {'name': 'da', 'age': 20}
    if id == 2:
        return {'user': 'alice', 'passward': '123456'}


if __name__ == '__main__':
    uvicorn.run(app='main:app', host="127.0.0.1", port=8000, reload=True, debug=True)

再次运行后,结果如下:

请求URL:http://127.0.0.1:8004/test/1,返回结果:

{
  "name": "da",
  "age": 20
}

请求URL:http://127.0.0.1:8004/test/2,返回结果:

 
{
  "user": "alice",
  "passward": "123456"
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值