当前位置: 首页 > news >正文

fastapi_No.7_获取表单和文件数据

前面几篇主要讲解的是fastapi在接收JSON数据时,该如何进行处理。但是在Web中存在表单和文件两种类型的数据传输情况。本篇中主要针对这两种数据类型进行讲解。

表单数据

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

# 激活虚拟环境
cd env/Scripts
activate
# 安装python-multipart包
pip install python-multipart

使用方法

要获取表单数据,就是要在路径操作函数中定义响应的变量,且该变量的默认值为Form函数的返回值。
下面是后端代码:

from random import paretovariate
from fastapi import FastAPI
# 演示获取表单数据的步骤
# 第一步:导入Form函数
from fastapi import Form
# 第二步:创建一个FastAPI类的实例对象
app = FastAPI()
# 第三步:创建一个路径装饰器
@app.post("/register")
# 第四步:创建一个路径操作函数,声明Form表单变量
async def create_user(username: str = Form(), password: str = Form()):
    return {
        "result": "register successfully",
        "username": username,
        "password": password
    }
# 第五步:运行服务器
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app="main:app", host="127.0.0.1", port=8080, reload=True)

下面是前端测试页面代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>register</title>
</head>

<body>
    <h2>这是一个测试fastapi获取表单数据的页面</h2>
    <!--action路径需要和后端定义的路径匹配!!!-->
    <form action="http://127.0.0.1:8080/register" method="post">
        <label for="name">用户名:</label><input type="text" name="username" id="name"><br>
        <label for="pwd">密码:</label><input type="password" name="password" id="pwd"><br>
        <button type="submit">注册</button>
    </form>
</body>

</html>

下面是测试结果:
前端输入截图
后端响应截图

表单字段注意事项

根据HTTP协议规定一次请求体中不能具有两种编码格式。
所以在一个路径操作函数中可以声明多个Form参数,但不能同时声明要接收JSON的Body字段。这是因为Form字段的编码是application/x-www-form-urlencoded,而Body字段的编码是application/json。

文件数据

File函数方式

使用File函数方式和使用Form函数方式相同,在路径操作函数中将文件参数的默认值设定为File函数的返回值。
下面是后端的代码示例:

# 演示接收文件数据
# File方式,利用File来声明这个变量接收的是一个文件数据
from fastapi import File
@app.post("/file/file")
# 此处的...表示None,...表示省略第一个形参
# filename需要和前端的变量名一致
async def get_file(filename:bytes = File(...)):
    return {"file_size":len(filename)}

下面是前端的代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h2>这是用来演示fastapi接收文件数据的前端演示</h2>
    <form action="http://127.0.0.1:8080/file/file" method="post" enctype="multipart/form-data">
    <!--注意此处filename必须和后端文件参数变量名一致-->
        <label for="file1"></label><input type="file" name="filename" id="file1">
        <button type="submit">上传</button>
    </form>

</body>

</html>

下面是演示结果:
前端演示结果
演示结果

UploadFile类方式

利用fastapi包中的UploadFile类,来声明变量的数据类型,以引入文件参数。
后端代码演示如下:

# 演示UploadFile类接收文件数据
# UploadFile方式,利用UploadFile来声明变量的类型
from fastapi import UploadFile
@app.post("/file/uploadfile")
async def get_uploadfile(file:UploadFile):
    # filename:上传文件名字符串(str),例如, myimage.jpg;
    # content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg;
    return{
        "filename":file.filename,
        "content_type":file.content_type
    }

前端代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h2>这是用来演示fastapi接收文件数据的前端演示</h2>
    <!--form 中包含文件时编码格式应该是multipart/form-data-->
    <form action="http://127.0.0.1:8080/file/uploadfile" method="post" enctype="multipart/form-data">
        <label for="file">文件</label><input type="file" name="file" id="file">
        <button type="submit">上传文件</button>
    </form>
</body>

</html>

演示结果:
前端界面
演示结果

多文件数据获取

想获取多个文件数据,只需要将接收文件数据的变量类型声明为列表即可。
后端代码如下:

# 演示File和UploadFile接收多文件数据
# 接收多文件时需要将接收文件类型的参数,声明为包含文件的列表形式
from typing import List
@app.post("/files/file")
async def get_files(files:List[bytes]=File(...)):
    return {
        "file_number":len(files)
    }
    
@app.post("/files/uploadfile")
async def get_files(files:List[UploadFile]):
    filesname = [file.filename for file in files]
    return { "filesname":filesname}

前端代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Files</title>
</head>

<body>
    <h2>演示File的多文件数据引用</h2>
    <form action="http://127.0.0.1:8080/files/file" method="post" enctype="multipart/form-data">
        <label for="files">
            文件名:
        </label>
        <input type="file" name="files" id="files" multiple>
        <button type="submit">上传文件</button>
    </form>

    <h2>演示UploadFile的多文件数据引用</h2>
    <form action="http://127.0.0.1:8080/files/uploadfile" method="post" enctype="multipart/form-data">
        <label for="files">
            文件名:
        </label>
        <input type="file" name="files" id="files" multiple>
        <button type="submit">上传文件</button>
    </form>

</body>

</html>

演示结果:
File方式获取多个文件
演示结果
UploadFile方式获取多个文件
演示结果

File和UploadFile方式的优缺点

方式优点缺点
File()将文件的所有内容都存储在内存里,适用于小型文件不适合存储大文件
UploadFile使用spooled文件:存储在内存的文件超出最大上限时,fastapi会把文件存入磁盘。适合处理图像,视频,二进制等大型文件,不会占用所有内存。自带file-like async接口,可以像操作文件一样操作文件数据

表单和文件混合

有时候在一个表单中可能既包含表单数据又包含文件数据,这种情况fastapi也是支持的。只需声明各个数据所对应的数据类型即可。
需要注意的是在前端中对form的编码需设定为multipart/form-data。
后端示例代码

# 演示既接收Form数据又接收文件数据
@app.post("/mixdata")
async def get_mixdata(username=Form(),file:UploadFile=File()):
    return {
        "username":username,
        "filename":file.filename
    }

前端示例代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h2>这是用来演示fastapi接收混合表单数据的前端演示</h2>
    <!--form 中包含文件时编码格式应该是multipart/form-data-->
    <form action="http://127.0.0.1:8080/mixdata" method="post" enctype="multipart/form-data">
        <label for="username">用户名:</label><input type="text" name="username" id="username"><br>
        <label for="file">文件:</label><input type="file" name="file" id="file"><br>
        <button type="submit">提交</button>
    </form>
</body>

</html>

演示结果:

前端输入
结果

相关文章:

  • 七牛加速 wordpress/怎么提高seo关键词排名
  • 最新网站建设技术/盐城网站优化
  • 小程序连接wordpress/搜索引擎优化培训中心
  • 网站要怎么做才能获得市场份额/今天最火的新闻头条
  • 网站用自己的电脑做服务器/品牌推广案例
  • 网站开发西安/百度搜索指数排行
  • YOLOX 学习笔记
  • 6.链表篇2链表的介绍和实现(单/双链表)
  • myj的补作业计划HrbustOJ新生赛(struct+优先队列)
  • Day770.Redis客户端如何与服务器端交换命令和数据 -Redis 核心技术与实战
  • 图像运算和图像增强二
  • 图学习——02.Graph Neural Network
  • Java学习笔记 ---- 类变量和类方法
  • smart原则简单案例,java规则引擎使用场景
  • 高阶数据结构 —— 红黑树(较平衡搜索树)
  • 矩阵的基本性质【转置/求逆/伴随等】
  • 【PyTorch深度学习项目实战100例】—— 基于Transformer实现电影评论星级分类任务 | 第42例
  • mysql的多种安装方式(Linux+Windows)