接收的不是 JSON,而是表单字段时,要使用 Form。
表单数据的「媒体类型」编码一般为 application/x-www-form-urlencoded。
要使用表单,需预先安装 python-multipart。
pip install python-multipart关于 “表单字段”
与 JSON 不同,HTML 表单(<form></form>)向服务器发送数据通常使用「特殊」的编码。
FastAPI 要确保从正确的位置读取数据,而不是读取 JSON。
可在一个路径操作中声明多个
Form参数,但不能同时声明要接收 JSON 的Body字段。因为此时请求体的编码是application/x-www-form-urlencoded,不是application/json。 这不是 FastAPI 的问题,而是 HTTP 协议的规定。
导入 Form
从 fastapi 导入 Form:
from fastapi import FastAPI, Form创建表单(Form)参数的方式与 Body 和 Query 一样(Form 是直接继承自 Body 的类。):
async def login(username: str = Form(), password: str = Form()):例如,OAuth2 规范的 “密码流” 模式规定要通过表单字段发送 username 和 password。
该规范要求字段必须命名为 username 和 password,并通过表单字段发送,不能用 JSON。
使用 Form 可以声明与 Body (及 Query、Path、Cookie)相同的元数据和验证。
templates模板
需安装jinja2模板
代码语言:javascript复制pip install jinja2在项目根目录创建 templates 模板目录 ![[Pasted image 20230901170025.png]] 前面html代码
代码语言:javascript复制<!DOCTYPE html> <html lang="en"> <head>
<meta charset="UTF-8">
<title>登录</title> </head> <body>
<form method="post">
<p>{{login_tip}}</p>
<div>
<label for="username">请输入用户名</label>
<input type="text" id="username" name="username">
</div>
<div>
<label for="password">请输入用户名</label>
<input type="password" id="password" name="password">
</div>
<input type="submit" value="提交">
</form> </body> </html>Form 表单提交
代码语言:javascript复制from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount(
"/static",
StaticFiles(directory="static"),
name="static" )
templates = Jinja2Templates(directory="templates")
@app.get("/login/", response_class=HTMLResponse) async def read_item(request: Request):
print(request.method)
return templates.TemplateResponse(
"login.html", context={
'request': request, 'login_tip': '用户登录'
}
)
@app.post("/login/") async def login(
username: str = Form(),
password: str = Form() ):
return {"username": username}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
app='main:app',
host="127.0.0.1",
port=8000, reload=True
)


