随笔 - 214  文章 - 12  评论 - 40  阅读 - 38万

FastAPI Response(一) Response模型

作者:麦克煎蛋   出处:https://www.cnblogs.com/mazhiyong/ 转载请保留这段声明,谢谢!

 

一、Response模型

在路径操作中,我们可以用参数response_model来声明Response模型。

复制代码
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None
    tags: List[str] = []


@app.post("/items/", response_model=Item)
async def create_item(item: Item):
    return item
复制代码

注意response_model是装饰器方法(get,post等)的参数。

 

Response模型可以是一个Pydantic模型,也可以是一个Pydantic模型的列表,例如List[Item]。

支持任意路径操作:

@app.get()
@app.post()
@app.put()
@app.delete()

 

FastAPI利用Response模型实现以下功能:

1、将输出数据转换成声明的Response模型。

2、对数据进行校验

3、生成自动化文档

4、(最重要的)限制输出数据只能是所声明的Response模型。

二、输入输出模型示例

复制代码
# 可能需要安装email-validator  -->  pip install email-validator 

from
fastapi import FastAPI from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: str = None class UserOut(BaseModel): username: str email: EmailStr full_name: str = None @app.post("/user/", response_model=UserOut) async def create_user(*, user: UserIn): return user
复制代码

如上所示,虽然路径操作函数返回的结果是user(包含了password),但我们声明的Response模型是UserOut(不包含password)。

FastAPI会过滤掉所有不在输出模型中的数据,因此最终的输出结果里并没有password。

如果输入内容如下:

{
    "username": "user",
    "password": "1234",
    "email": "user@qq.com",
    "full_name": "full_name"
}

那么输出结果为:

{
    "username": "user",
    "email": "user@qq.com",
    "full_name": "full_name"
}

三、Response模型参数

1、Response模型可以有缺省值。

复制代码
from typing import List

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = 10.5
    tags: List[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
async def read_item(item_id: str):
    return items[item_id]
复制代码

2、返回实际有效数据

有时候我们只想返回被真正设置过的数据,而忽略其他未被设置过的或者缺省数据。

我们可以用参数response_model_exclude_unset来实现这个目的。如上所示代码。

复制代码
# 访问:
http://127.0.0.1:8000/items/foo

# 返回结果:
{
    "name": "Foo",
    "price": 50.2
}
复制代码

3、参数 response_model_includeresponse_model_exclude

这两个参数接收Response模型的部分属性集合,分别表示包含(排除剩下的)和排除(包含剩下的)集合里的属性。

在实际工作中,我们应该尽量少利用这两个参数,而是应该声明不同的类表示不同的数据需求,这样更利于数据维护和逻辑清晰。

复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = 10.5


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
    "baz": {
        "name": "Baz",
        "description": "There goes my baz",
        "price": 50.2,
        "tax": 10.5,
    },
}


@app.get("/items/{item_id}/name", response_model=Item, response_model_include={"name", "description"})
async def read_item_name(item_id: str):
    return items[item_id]


@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"})
async def read_item_public_data(item_id: str):
    return items[item_id]
复制代码

四、Response联合模型

我们可以声明Response模型是一个Union类型(包含两种类型),实际返回结果可以是Union其中任何一个。

复制代码
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class BaseItem(BaseModel):
    description: str
    type: str


class CarItem(BaseItem):
    type = "car"


class PlaneItem(BaseItem):
    type = "plane"
    size: int


items = {
    "item1": {"description": "All my friends drive a low rider", "type": "car"},
    "item2": {
        "description": "Music is my aeroplane, it's my aeroplane",
        "type": "plane",
        "size": 5,
    },
}


@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
    return items[item_id]
复制代码

这里PlaneItem、CarItem均从BaseItem继承而来,提高代码复用,也便于代码维护。

五、Response列表模型

Response模型也可以是一个列表。

复制代码
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str


items = [
    {"name": "Foo", "description": "There comes my hero"},
    {"name": "Red", "description": "It's my aeroplane"},
]


@app.get("/items/", response_model=List[Item])
async def read_items():
    return items
复制代码

六、Response字典模型

我们也可以不用Pydantic模型,而是直接基于字典来声明Response模型。

复制代码
from typing import Dict
from fastapi import FastAPI

app = FastAPI()


@app.get("/keyword-weights/", response_model=Dict[str, float])
async def read_keyword_weights():
    return {"foo": 2.3, "bar": 3.4}
复制代码

 

posted on   麦克煎蛋  阅读(4225)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示