FastAPI学习-7.登录页面-表单数据 form

2023-09-11 19:37:51 浏览数 (17)

接收的不是 JSON,而是表单字段时,要使用 Form。 表单数据的「媒体类型」编码一般为 application/x-www-form-urlencoded

要使用表单,需预先安装 python-multipart

代码语言:javascript复制
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

代码语言:javascript复制
from fastapi import FastAPI, Form

创建表单(Form)参数的方式与 BodyQuery 一样(Form 是直接继承自 Body 的类。):

代码语言:javascript复制
async def login(username: str = Form(), password: str = Form()):

例如,OAuth2 规范的 “密码流” 模式规定要通过表单字段发送 usernamepassword

该规范要求字段必须命名为 usernamepassword,并通过表单字段发送,不能用 JSON。

使用 Form 可以声明与 Body (及 QueryPathCookie)相同的元数据和验证。

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  
    )

0 人点赞