FastAPI异步API初学

1.Fastapi的优势

1.异步任务 处理快 相比于同步任务 

异步任务可以同时处理多个任务 而同步只能将一个任务执行完毕后再去 相比之下异步任务的速度和效率更快 

2.核心用到async和await 一个都不能少

async 是定义一个协程函数

await是再协程函数中的挂起

2.Fastapi的用法

1.get

@user_router.get("/select_user")
async def get_user_list():
    users = await User.all()
    return {"code": 200, "data": users}

@user_router.get("/select_user") 括号中的是路由 可以自定义

async def 方法名字() 中间可以传值 如id:int name:str 前面为要传的变量名 后面为类型

@app.get("/hello/{name}")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}

如果是/{name}类型的 那么方法中传的数据变量名要与路径中的变量名相等 

url……/hello/1/  路由就相等这个样子 path 可以为变量加约束 如:

(name: str=Path(
    ...,
    title="Name",
    min_length=1,
    max_length=10,
    example="Mike"
)):

··· 是必填 也可以为None 可以为空的意思 如果是必填不填就会出现下面场景

title 就是我们的提示

min_legth 最小长度为1 max_length 最大的长度 example 是示例 这样就算自动校验的方法

@user_router.get("/select_user")
async def get_user_list():
    users = await User.all()
    return {"code": 200, "data": users}

这个就是查询 User中的所有内容 前面要挂载 await 再django中是 models.User.object.all()

区别就是去掉models 和 object 在前面加上 await

如果需要条件查询我们如下:

@task_router.get("/")
async def get_task_list(
    status: int = None,
    keyword: str = None,
    sort_by: str = None,
):
    query = Task.all()
    if status is not None:
        query = query.filter(status=status)
    if keyword:
        query = query.filter(Q(title__contains=keyword))
    if sort_by:
        query = query.order_by(sort_by)

    task_list = await query
    return {"code": 200, "data": task_list}

我们将条件加入 都作为选填 =None 这样我们如果不填就是查询所有内容

我们定义query=Task.all 是查询Task中的所有内容 赋值给 query

下面判断如果我们输入了内容 就filter进行查询然后重新赋值给query 

最后是sort_by 用哪个字段排序 await query 赋值给task_list 输出

2.post

实现我们添加是要写一个请求体 

class TaskCreateRequest(BaseModel):
    user_id:int =Field(
        None,
        title="用户ID",
        description="用户ID",
        example=1
    )
    title : str
    description : str
    status : int
    priority : int
    due_date : str

请求体我们新建文件 schemas 然后在下面新建.py 在里面新建请求体 请求体中的字段要与模型中的字端对应 并且后面携带类型 也可以在后加约束 相当于校验

比如 第一个user_id 第一个为选填 如果是必填我们就写··· 如果不是我们就写None 

title是标题 description就是提示 example就是示例 跟我们前面写的是一样的 

然后是post添加 我们调用这个 TaskCreateRequest 请求体

@task_router.post("/add")
async def create_task(task_data: TaskCreateRequest):
    task = await Task.create(**task_data.dict())
    return {"code": 200,"msg":"创建成功","data": task}

我们传的参数     task_data: TaskCreateRequest

接受前端传的内容 然后走我们的请求体判断 

task = await Task.create(**task_data.dict())

将 task_data.dict 转化为字典 添加到Task中 并且挂载一个 await

下面就是添加的请求体 基本都是必填的 也可以为选填

3.put

put和post一样都需要请求体 但是不一样的是 put的请求体 可以选填 而且我们可以传空值

class TaskUpdateRequest(BaseModel):
    user_id:int =Field(
        None,
        title="用户ID",
        description="用户ID",
        example=1
    )
    title : str=Field(
        None,
        title="任务标题",
        description="任务标题",
        example="任务标题"
    )
    description : str=Field(
        None,
        title="任务详情",
        description="任务详情",
        example="任务详情"
    )
    status : int=Field(
        None,
        title="任务状态",
        description="任务状态",
        example=0
    )
    priority : int=Field(
        None,
        title="任务优先级",
        description="任务优先级",
        example=1
    )
    due_date : str=Field(
        None,
        title="任务截止时间",
        description="任务截止时间",
        example="2023-01-01 00:00:00"
    )

把所有的请求体都设置为可以为None就是我们前端可以不修改这个字段

@task_router.put("/update/{id}")
async def update_task(id: int, task_data: TaskUpdateRequest):
    task = await Task.filter(id=id).first()
    if not task:
        return {"code": 404, "message": "任务不存在"}
    update_dict = task_data.model_dump(exclude_unset=True)
    await task.update_from_dict(update_dict)
    await task.save()
    return {"code": 200, "message": "更新成功", "data": task}

我们传了一个id 是我们要修改任务的id 在任务列表中查找

查找后 我们 task_data.model_dump(exclude_unset=True)

将前端传入的数据 变为一个字典 只传不为None的值 这样就不会报错了 然后用

update_form_dict 进行修改就可以了

如果我们不写(exclude_unset=True) 则会一直显示我们传的值不够

4.delete

删除只需要我们在url中传一个id就可以了

@task_router.delete("/delete/{id}")
async def delete_task(id: int):
    task = await Task.filter(id=id).first()
    if not task:
        return {"code": 404, "message": "任务不存在"}
    await task.delete()
    return {"code": 200, "message": "删除成功"}

在task中查找id 然后直接调用方法 delete就可以删除了 前面要加一个await挂载才可以使用

总结

今天学习了fastapi 的基本使用方法 以及models的创建 和挂载 以及什么是请求体 跟django的方法类似 async和await必须同时使用 django的方法现在改为前面加上await 

多文件下的方法 如models routers schemas 每个文件下的py不一样 要严格分开 

以及数据库的连接 迁移 数据查询 添加 修改 删除

pip install aerich

aerich init -t day01.config.TORTOISE_ORM
aerich init-db
严格按照要求 每个的配置不一样 如果要生成token 登陆验证 我们还需要加入jwt 生成前端页面要加上我们的跨域挂载

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
book_project/
├── main.py                          # FastAPI应用主入口
│
├── requirements.txt                 # Python依赖包
│
└── app/                             # 应用核心代码
    ├── __init__.py
    │
    ├── config.py                    # 数据库配置文件
    │
    ├── models/                      # 数据模型层 
    │   ├── __init__.py
    │   ├── models.py                  # 相关模型
    │
    ├── routers/                     # API路由层
    │   ├── __init__.py
    │   └── work.py                  # 相关API
    │
    └── schemas/                     # 数据验证层 (Pydantic)
        ├── __init__.py
        └── work.py                  # 请求/响应模型

文件夹结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值