在上一篇文章中,我们使用FastAPI编写了一个Flask风格的demo。在这篇文章里我们继续接着上篇的内容对FastAPI进行探究,这里面就包括了请求参数的处理,数据库的连接等。好了闲话少说,现在就开始这篇的内容。
获取路径参数- 跟flask框架一样,fastapi也提供从url中获取参数的能力,具体怎么获取的我们用例子说明一些,代码如下所示:
├── app
│ ├── api
│ │ ├── __init__.py
│ │ └── users.py
│ ├── __init__.py
├── manage.py
2. 打开app/api/users.py文件,键入如下代码:
# app/api/users.py
@users.get("/get_user/{id}")
async def get_user_by_id(id: int):
if id > 0:
return {"username": "admin", "msg": "success", "code": 200}
return {"msg": "failed", "code": 401}
3. 启动服务,并测试
分别打开两个bash,输入以下命令
curl -X GET "http://192.168.2.124:9000/api/get_user/0"
{"msg":"failed","code":401}%
curl -X GET "http://192.168.2.124:9000/api/get_user/10"
{"username":"admin","msg":"success","code":200}%
服务日志信息如下
python manage.py
INFO: Started server process [65515]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:9000 (Press CTRL C to quit)
INFO: 192.168.2.207:54530 - "GET /api/get_user/0 HTTP/1.1" 200 OK
INFO: 192.168.2.207:54532 - "GET /api/get_user/10 HTTP/1.1" 200 OK
获取表单数据
当我们需要从表单中获取用户输入的数据使这个使用就需要使用到Form了
- 想要使用Form就需要提前安装python-multipart这个库
pip install python-multipart -i https://pypi.tuna.tsinghua.edu.cn/simple
2. 在视图函数中使用Form对象,具体代码如下所示:
# app/api/users.py
from fastapi import APIRouter, Form
users = APIRouter()
@users.post("/login")
async def login(username: str = Form(), password: str = Form()):
if username and password:
return {"msg": "success", "code": 200}
return {"msg": "failed", "code": 401}
运行测试结果如下所示
curl -X POST -F "username=admin" -F "password=admin" "http://192.168.2.124:9000/api/login"
{"msg":"success","code":200}%
# 服务器运行日志输出如下
python manage.py
INFO: Started server process [65590]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:9000 (Press CTRL C to quit)
INFO: 192.168.2.207:54534 - "POST /api/login HTTP/1.1" 200 OK
配置数据库和创建数据模型
很多web大都会提供一些orm的插件或者功能,例如Django就内置了orm,但是与之不一样的地方是像flask和fastapi这些小型框架却没有内置相对应的orm框架,而另辟蹊径采用插件集成的方式来支持数据的操作,这样做的好处是灵活,选择多。
- 安装tortoise-orm和aiomysql驱动
我们选择tortoise-orm这个第三方的orm框架,这个框架是参考django内置orm开发的
pip install tortoise-orm -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install aiomysql -i https://pypi.tuna.tsinghua.edu.cn/simple
2. 定义数据模型
# touch app/models/models.py创建模型文件
from tortoise import fields
from tortoise.models import Model
class User(Model):
id = fields.IntField(pk=True)
username = fields.CharField(max_length=30, unique=True, description="用户名")
password = fields.CharField(max_length=128, description="密码")
3. 配置数据连接信息和初始化数据库
from fastapi import FastAPI
from tortoise.contrib.fastapi import register_tortoise
def create_app() -> FastAPI:
app = FastAPI()
register_rotuer(app)
register_db(app)
return app
def register_rotuer(app: FastAPI) -> None:
"""注册路由"""
from app.api import routers
app.include_router(routers)
def register_db(app: FastAPI) -> None:
""""初始化数据库并根据数据模型生成对应的表"""
register_tortoise(
app,
db_url="mysql://root:root12345678@192.168.2.124:3306/item_name",
modules={"models": ["app.models.models"]},# 这是一个列表用来指明我们的模型文件的路径
generate_schemas=True,
add_exception_handlers=True)
测试运行,登录mysql查看是否生成了数据表
python manage.py
INFO: Started server process [66742]
INFO: Waiting for application startup.
/home/test/env/lib/python3.10/site-packages/aiomysql/cursors.py:239: Warning: Table 'user' already exists
await self._query(query)
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:9000 (Press CTRL C to quit)
查看是否创建了数据表
mysql> desc user;
---------- -------------- ------ ----- --------- ----------------
| Field | Type | Null | Key | Default | Extra |
---------- -------------- ------ ----- --------- ----------------
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| password | varchar(128) | NO | | NULL | |
---------- -------------- ------ ----- --------- ----------------
3 rows in set (0.00 sec)
在视图函数中操作模型数据
fastapi在视图函数中操作模型数据跟在flask中操作是类似的,具体如下所示
# app/api/users.py
from fastapi import APIRouter, Form
from app.models.models import User
users = APIRouter()
@users.post("/login")
async def login(username: str = Form(), password: str = Form()):
if username and password:
return {"msg": "success", "code": 200}
return {"msg": "failed", "code": 401}
@users.get("/get_users")
async def get_users():
return {"msg": "success", "code": 200}
@users.get("/get_user/{id}")
async def get_user_by_id(id: int):
if id > 0:
return {"username": "admin", "msg": "success", "code": 200}
return {"msg": "failed", "code": 401}
@users.post("/add")
async def add(username: str = Form(), password: str = Form()):
if username and password:
u = await User.create(username=username, password=password)
if u:
return {"msg": "create user success", "code": 200}
return {"msg": "create user failed", "code": 403}
@users.get("/get_user/{id}")
async def get_user(id: int):
if id:
data = await User.filter(id=id).first()
return {"data": data, "msg": "success", "code": 200}
return {"data": "", "msg": "success", "code": 200}
@users.post("/update_user")
async def update_user(id: str = Form(), name: str = Form()):
if name and id:
id = int(id)
await User.filter(id=id).update(username=name)
return {"msg": "success", "code": 200}
return {"msg": "failed", "code": 400}
@users.get("/delete_user/{id}")
async def delete(id: int):
if id:
await User.filter(id=id).delete()
return {"msg": "success", "code": 200}
return {"msg": "failed", "code": 400}
运行测试结果如下所示:
curl -X POST -F "username=admin3" -F "password=admin3" "http://192.168.2.124:9000/api/add"
{"msg":"create user success","code":200}%
curl -X GET "http://192.168.2.124:9000/api/get_user/1"
{"username":"admin","msg":"success","code":200}%
curl -X POST -F "id=2" -F "name=admin2" "http://192.168.2.124:9000/api/update_user"
{"msg":"success","code":200}%
curl -X GET "http://192.168.2.124:9000/api/delete_user/2"
{"msg":"success","code":200}%
# 服务器运行输出日志如下
python manage.py
INFO: Started server process [67038]
INFO: Waiting for application startup.
/home/test/env/lib/python3.10/site-packages/aiomysql/cursors.py:239: Warning: Table 'user' already exists
await self._query(query)
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:9000 (Press CTRL C to quit)
INFO: 192.168.2.207:54572 - "POST /api/add HTTP/1.1" 200 OK
INFO: 192.168.2.207:54574 - "GET /api/get_user/1 HTTP/1.1" 200 OK
INFO: 192.168.2.207:54576 - "POST /api/update_user HTTP/1.1" 200 OK
INFO: 192.168.2.207:54578 - "GET /api/delete_user/2 HTTP/1.1" 200 OK
demo程序最终目录结构如下所示:
.
├── app
│ ├── api
│ │ ├── __init__.py
│ │ └── users.py
│ ├── __init__.py
│ ├── models
│ │ ├── __init__.py
│ │ ├── models.py
├── manage.py
小结
通过前后两篇文章我们大概知道了怎么去使用fastapi和其他插件来组织和编写web应用服务,虽然这其中的细节没有我没有细说,但是我觉得目前懂得怎么用就行了,细节方面我们在慢慢的进行补充就行了,fastapi的官方文档还是比较清晰易懂的(总之一句话有手就行,哈哈哈)。谢谢你能看到结尾,希望能帮到正在学习fastapi这个框架的你吧。