一、响应模型

使用路径操作装饰器的 response_model 参数来定义响应模型

1.1 response_model

前面写的这么多路径函数最终 return 的都是自定义结构的字典,FastAPI 提供了 response_model 参数,声明 return 响应体的模型

# 路径操作
@app.post("/items/", response_model=Item)
# 路径函数
async def create_item(item: Item):
    ...

response_model 是路径操作的参数,并不是路径函数的参数

FastAPI将使用response_model进行以下操作:

  • 将输出数据转换为response_model中声明的数据类型。
  • 验证数据结构和类型
  • 将输出数据限制为该model定义的
  • 添加到OpenAPI中
  • 在自动文档系统中使用。

你可以在任意的路径操作中使用 response_model 参数来声明用于响应的模型

案例:

  • 注册功能
  • 输入账号、密码、昵称、邮箱,注册成功后返回个人信息
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
import uvicorn

app = FastAPI()


class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: Union[str, None] = None

# 用户输出
class UserOut(BaseModel):
    username: str
    email: EmailStr
    full_name: Union[str, None] = None


@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
    return user


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

这里用到了EmailStr库,需要单独下载

pip install email-validator

启动并请求接口,查看返回。
在这里插入图片描述

1.2 response_model_exclude_unset

通过上面的例子,我们学到了如何用response_model控制响应体结构,但是如果它们实际上没有存储,则可能要从结果中忽略它们。例如,如果model在NoSQL数据库中具有很多可选属性,但是不想发送很长的JSON响应,其中包含默认值。

案例:

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

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = 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": []},
}


# response_model_exclude_unset 排除没有设置的值
@app.get("/items/{item_id}", 
				response_model=Item, 
				response_model_exclude_unset=True/False
				)
async def read_item(item_id: str):
    return items[item_id]

请求:http://127.0.0.1:8080/items/foo

设置unset参数:response_model_exclude_unset=True

在这里插入图片描述

不设置unset参数:response_model_exclude_unset=False

在这里插入图片描述

使用路径操作装饰器的 response_model 参数来定义响应模型,特别是确保私有数据被过滤掉。使用 response_model_exclude_unset 来仅返回显式设定的值。
除了response_model_exclude_unset以外,还有response_model_exclude_defaultsresponse_model_exclude_none,我们可以很直观的了解到他们的意思,不返回是默认值的字段和不返回是None的字段。

1.3 response_model_exclude_none

用于接口只返回结果中不为None的值

# response_model_exclude_unset 排除没有设置的值
@app.get("/items/{item_id}", 
				response_model=Item, 
				response_model_exclude_none=True
				)
async def read_item(item_id: str):
    return items[item_id]

在这里插入图片描述

description 由于为none,字段不显示

1.4 response_model_include

用于接口只返回我们设定的值

# response_model_include 只显示设定的值
@app.get("/items/{item_id}", 
				response_model=Item, 
				response_model_include={"name", "price"}  # 只显示设定的值
				)
async def read_item(item_id: str):
    return items[item_id]

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": []},
    }

在这里插入图片描述

1.5 response_model_exclude

用于不显示设定的值,

# response_model_exclude 不显示设定的值
@app.get("/items/{item_id}", 
				response_model=Item, 
				response_model_exclude ={"tag",}  # 不显示设定的值
				)
async def read_item(item_id: str):
    return items[item_id]

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": []},
    }

在这里插入图片描述
适用场景:数据都是同一份(统一的数据模型),加了这些参数之后,我们可以根据不同的接口,返回不同的数据,这样比较灵活

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐