FastAPI(二)数据模型

1. 数据模型

这一部分介绍 Pydantic 数据模型的定义,并通过 response_model 指定返回数据格式。

import uvicorn
from pydantic import BaseModel
from fastapi import FastAPI

app = FastAPI()

class Request(BaseModel):
    name : str = 'undefined'
    age : int = 0


class Status(BaseModel):
    is_status1 : bool = False
    is_status2 : bool = False


class Response(BaseModel):
    grade: int
    score: int
    status : Status = {True, True}


# response_model 设置响应数据类型
@app.post('/demo', response_model=Response)
# request 设置传递进来的数据类型
async def demo(request : Request):
    return {'grade': 1001, 'score': 85, 'status': Status(is_status1=True, is_status2=False)}


if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)
curl -X POST http://127.0.0.1:8000/demo -H "Content-Type: application/json" -d "{\"name\": \"smith\", \"age\": 25}"

2. 数据校验

这一部分展示如何使用 Pydantic 的 Field 进行数据校验,包括字符串格式、数值范围及小数精度等。

import uvicorn
from pydantic import BaseModel
from pydantic import Field
from fastapi import FastAPI
from fastapi import Path
from fastapi import Query
from decimal import Decimal

app = FastAPI()

# 1. 请求和响应数据校验
class Data(BaseModel):
    # 字段默认指是undefined,最小长度2,最大长度10,必须满足前面是字母后面是数字的格式
    name : str = Field('undefined', min_length=2, max_length=10, pattern='^[a-zA-Z]+[0-9]+$')
    # 字段默认值是0,必须大于等于10,小于等于20,同时必须是2的倍数
    age : int = Field(0, ge=10, le=20, multiple_of=2)
    # 字段默认值是0.0,整个数字最大位数是5,小数部分位数是2,整数部分位数为3
    # 注意:Decimal 和 float 都是表示小数的类型,不同的是前者使用十进制方式进行存储,精度更好
    salary : Decimal = Field(0.0, max_digits=5, decimal_places=2)

@app.post('/demo01', response_model=Data)
async def demo01(data : Data):
    return data


# 2. 路径和请求参数校验
# path_param 为路径参数
# query_param 为请求参数
@app.post('/demo02/{path_param}')
# path_param 最小长度2,最大长度5,注意: Path 不可以设置默认值
# query_param 默认值 0,必须大于等于0并且小于20
async def demo02(path_param : str = Path(min_length=2, max_length=5),
                 query_param : int = Query(0, ge=0, lt=20)):
    return {'path_param': path_param, 'query_param': query_param}


if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)