请求体数据【重点】
1. Pydantic 使用
当你需要将数据从客户端(例如浏览器)发送给 API 时,你将其作为「请求体」发送。请求体是客户端发送给 API 的数据。响应
体是 API发送给客户端的数据。
FastAPI 基于 Pydantic , Pydantic 主要用来做类型强制检查校验数据)。不符合类型要求就会抛出异常。
对于 API服务,支持类型检查非常有用,会让服务更加健壮,也会加快开发速度,因为开发者再也不用自己写一行一行的做类型
检查。
安装上手pip install pydantic
from fastapi import APIRouter
from pydantic import BaseModel
from datetime import date
from typing import List
app03 = APIRouter()
# 定义一个 Pydantic 模型类 User
class User(BaseModel):
name: str
age: int
birth: date
friends: List[int] = []
# 定义一个处理 POST 请求的路由 /user
@app03.post('/user')
async def user(user: User): # 接收一个 User 类型的数据
print(user, type(user))
print(user.name, user.birth)
print(user.dict()) # 打印用户对象转换为字典后的结果
return user
测试我们可以看到,在请求体里可以自行输入些值。然后给了响应。
这个是我们打印出来的,注意观察下。
2. 类型转换
上面的age和friends的值,我们填写的都是int类型。如果前端填写了字符串类型呢?
测试下:
我们发现,并没有报错,反而自动转换成了int类型。说明它是可以自动转换的。但我们怕的就是它转不过来,比如下面:
总结:当输入类型不一致的时候,不一定报错。它会尝试帮您转换。当转换再失败,这个时候才会抛错。
3. 其他写法
class User(BaseModel):
name: str = 'root' # 默认值
age: int = Field(default=0, gt=0, lt=100) #导入Field. 默认值=0,大于0,小于100
birth: Union[date, None] = None # 默认值None
friends: List[int] = []
description: Optional[str] = None # 默认值None
我们用120测试,就发现报错了,值必须小于100
4. Pydantic数据效验终极大招
- 用正则表达式限制字符串
我们来限制name输入规则:
class User(BaseModel):
name: str = Field(pattern='^a') # 正则表达式,要求首字母必须为a
age: int = Field(default=0, gt=0, lt=100)
birth: Union[date, None] = None
friends: List[int] = []
description: Optional[str] = None
我们还用原来的yuan来测试下,发现报错了。现在我们改为apple
这个时候就没有报错。
- 通过自定义函数,设置任意规则。
class User(BaseModel):
# name: str = Field(pattern='^a')
name: str
age: int = Field(default=0, gt=0, lt=100)
birth: Union[date, None] = None
friends: List[int] = []
description: Optional[str] = None
@field_validato,再定义装饰器r('name') # 需要导入field_validato,再定义装饰器
# 定义一个函数,必须为字母
def name_must_isisalpha(cls, value): #cls代表当前对象
# assert:断言。用法自行了解
assert value.isalpha(), 'name must is alpha'
return value
我们来输入apple123这种不符合规则的测试看下
5. 类型嵌套
- 第一种嵌套例子
假设我们新增一个address属性:
address:str
但我们一般会规定省市,所以这里可以用到类型嵌套
# 定义地址Address类
class Address(BaseModel):
province: str # 省份
city: str # 市区
class User(BaseModel):
# name: str = Field(pattern='^a')
name: str
age: int = Field(default=0, gt=0, lt=100)
birth: Union[date, None] = None
friends: List[int] = []
description: Optional[str] = None
address: Address # 嵌套
@field_validator('name')
def name_must_isisalpha(cls, value):
assert value.isalpha(), 'name must is alpha'
return value
测试看下,这个时候就需要让我们填写省份和市区了:
- 第二种嵌套例子
为了方便,我们只测试简单部分,方便了解
from fastapi import APIRouter
from pydantic import BaseModel, Field
from typing import List
app03 = APIRouter()
class User(BaseModel):
name: str
age: int = Field(default=0, gt=0, lt=100)
# Data类,把多个User类对象放进一个列表里
class Data(BaseModel):
data: List[User]
@app03.post('/user')
async def user(user: User):
return user
@app03.post('/data')
async def data(data: Date):
return data
这个时候,就可以看到,我们可以输入多个user对象的值。
响应也是没问题的。
6. 总结
这一章节比较重要,如果不明白的地方建议多搜索了解下,多练习熟悉