文章目录
1. response_model
2. 添加输出模型
3. 响应模型编码参数
4. response_model_include 和 response_model_exclude
5. 代码复用:继承
6. Union
7. 任意 dict 的响应
8. 响应状态码
9. 表单参数
1. response_model
响应模型 不是 路径参数
from typing import Optional, List from fastapi import Cookie, FastAPI, Header from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None tags: List[str] = [] @app.post("/items/", response_model=Item) # 装饰器方法的一个参数 async def create_items(item: Item): return item
or
@app.post("/items/", response_model=List[Item]) # 装饰器方法的一个参数 async def create_items(item: Item): return [item, item]
响应模型 对 返回的数据 进行转换,校验
例如:
from typing import Optional, List from fastapi import Cookie, FastAPI, Header from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: Optional[str] = None @app.post("/user/", response_model=UserIn) # 装饰器方法的一个参数 async def create_user(user: UserIn): return user
2. 添加输出模型
- 输出的时候不给密码,更改响应模型为不带密码的
from typing import Optional, List from fastapi import Cookie, FastAPI, Header from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: Optional[str] = None class UserOut(BaseModel): username: str email: EmailStr full_name: Optional[str] = None @app.post("/user/", response_model=UserOut) # 装饰器方法的一个参数 async def create_user(user: UserIn): return user
3. 响应模型编码参数
response_model_exclude_unset 参数 True,输出忽略 未明确设置的 字段
response_model_exclude_defaults=True,忽略跟默认值一样的字段
response_model_exclude_none=True,忽略 None 的字段
from typing import Optional, List from fastapi import Cookie, FastAPI, Header from pydantic import BaseModel, EmailStr app = FastAPI() class Item(BaseModel): name: str description: Optional[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]
如果参数 改为 False,或者 删除该参数,未设置的值 也显示出来了
4. response_model_include 和 response_model_exclude
它们接收一个由属性名称 str 组成的 set 来包含(忽略其他的)或者排除(包含其他的)这些属性
response_model_include, 只包含指定字段
response_model_exclude,排除指定字段
from typing import Optional, List from fastapi import Cookie, FastAPI, Header from pydantic import BaseModel, EmailStr app = FastAPI() class Item(BaseModel): name: str description: Optional[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"}, # { } 表示 set, 使用 [ ] 也可以 ) 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]
5. 代码复用:继承
from typing import Optional from fastapi import FastAPI from pydantic import EmailStr, BaseModel app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: Optional[str] = None class UserOut(BaseModel): username: str email: EmailStr full_name: Optional[str] = None class UserInDB(BaseModel): username: str hashed_password: str email: EmailStr full_name: Optional[str] = None def fake_password_hasher(raw_password: str): return "supersecret" + raw_password def fake_save_user(user_in: UserIn): hashed_password = fake_password_hasher(user_in.password) user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password) # 使用user_in的数据初始化UserInDB , 并添加hashed_password字段 print("User saved! ..not really") return user_in_db @app.post("/user/", response_model=UserOut) async def create_user(user_in: UserIn): user_saved = fake_save_user(user_in) return user_saved
- 通过继承进行复用
from typing import Optional from fastapi import FastAPI from pydantic import EmailStr, BaseModel app = FastAPI() class UserBase(BaseModel): username: str email: EmailStr full_name: Optional[str] = None class UserIn(UserBase): password: str class UserOut(UserBase): pass class UserInDB(UserBase): hashed_password: str def fake_password_hasher(raw_password: str): return "supersecret" + raw_password def fake_save_user(user_in: UserIn): hashed_password = fake_password_hasher(user_in.password) user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password) # 使用user_in的数据初始化UserInDB , 并添加hashed_password字段 print("User saved! ..not really") return user_in_db @app.post("/user/", response_model=UserOut) async def create_user(user_in: UserIn): user_saved = fake_save_user(user_in) return user_saved
6. Union
- 响应将是 多种类型中的 任何一种
from typing import Optional, Union 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]
关于 HTTP 状态码
在 HTTP 协议中,你将发送 3 位数的数字状态码作为响应的一部分。
100 及以上状态码用于「消息」响应。你很少直接使用它们。具有这些状态代码的响应不能带有响应体。
200 及以上状态码用于「成功」响应。这些是你最常使用的。
200 是默认状态代码,它表示一切「正常」。
另一个例子会是 201,「已创建」。它通常在数据库中创建了一条新记录后使用。
一个特殊的例子是 204,「无内容」。此响应在没有内容返回给客户端时使用,因此该响应不能包含响应体。
300 及以上状态码用于「重定向」。具有这些状态码的响应可能有或者可能没有响应体,但 304「未修改」是个例外,该响应不得含有响应体。
400 及以上状态码用于「客户端错误」响应。这些可能是你第二常使用的类型。
一个例子是 404,用于「未找到」响应。
对于来自客户端的一般错误,你可以只使用 400。
500 及以上状态码用于服务器端错误。你几乎永远不会直接使用它们。当你的应用程序代码或服务器中的某些部分出现问题时,它将自动返回这些状态代码之一。
from fastapi import FastAPI, status status_code=status.HTTP_201_CREATED # 可以使用代码补全,不必记住
9. 表单参数
- 接收的不是 JSON,而是表单字段时,要使用 Form
from fastapi import FastAPI, Form app = FastAPI() @app.post("/login/") async def login(username: str = Form(...), password: str = Form(...)): return {"username" : username}