flask 接口处理带有图片和json数据的请求 发送图片到前端的实现

1.flask的request

从flask的源码可以看到flask的可用属性很多,包括data,form,files,header,host等,在我们接收文件传参时需要用到的属性就是form和files。不过具体的使用方式有两种,即:postman发送的和requests模拟发送的。

2.通过postman 模拟发送图片的解决方案

如图所示,在headers中设置Content-Type 为multipart/form-data

在body中设置key和value

其中 文件的选择是通过点击select files进行选择的,这样从flask端接收文件时的代码如下:

python 复制代码
@camunda_power_bp.route('/repair/receipt/', methods=['POST'])
@format_func.json_none_blank
def repair_receipt():
    data = request.form.to_dict()
    print(data,type(data))
    if not isinstance(data,dict):
        try:
            data = json.loads(data)
        except Exception as e:
            print(e)
            message = {"code":1,"message":"参数不是json"}
            return json.dumps(message,ensure_ascii=False)
    print(request.form)
    #data = json.loads(data)
    images = request.files
    # print(request.files)
    if images:
        #image_addr_list = image_func.image_save(images,request)
        image_addr_list = image_func.image_save_form("file_imgs",request)
        print(image_addr_list)
    else:
        image_addr_list = []

代码中的request.form.to_dict()是用于接收form数据的,把postman的form字段进行转化成为字典,文件的接收则是通过request.files的方式。

对请求中的所有文件进行轮询的函数时image_save_form,如下:

python 复制代码
import os, sys

path1 = os.path.dirname(os.path.abspath(__file__))
path2 = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(path2)
sys.path.append(path1)

UPLOAD_PATH = os.path.join(path2, 'images')
from werkzeug.utils import secure_filename
def image_save_form(keyname,request):
    image_addr = []
    imgs = request.files.getlist(keyname)
    print(imgs)
    for img in imgs:
        filename = secure_filename(img.filename)
        print(filename)
        img.save(os.path.join(UPLOAD_PATH, filename))
        image_addr.append(os.path.join(UPLOAD_PATH, filename))
    return image_addr

按照以上方式将文件进行了保存。

3.通过requests模拟发送图片的解决方案

requests程序如下:

python 复制代码
import requests
def path_file():
    folder_path = os.path.join(path2, "images")
    # 使用os.listdir()获取文件夹下的所有文件和子文件夹名
    all_items = os.listdir(folder_path)
    # print(all_items)
    # 使用os.path.isfile()筛选出文件名
    file_names = [item for item in all_items if os.path.isfile(os.path.join(folder_path, item))]
    number = 1
    files = []
    for image_name in file_names:
        #image_name = os.path.basename(image)
        image_name_type = image_name.split(".")[-1]
        image_info = ("file"+str(number),(image_name,open(os.path.join(folder_path,image_name),'rb'),"image/"+image_name_type))
        number += 1
        files.append(image_info)
    #print(files)
    return files
    
def repair_recipt_image(proc_inst_id_list,assignee):
    """
    待开发:
    :return:
    """
    url = ip_addr + "/task/getdetail/imformation/"
    url2 = ip_addr + "/repair/receipt/"
        power_monitor = department_monitor("供配电")
        print(power_monitor)
        request_data = { "complete_status": "楚王好细腰",
                        "abnormality_situation": "宫中多饿死"}
        files = path_file()
        response_data = requests.post(url2, files=files,data=request_data)
        print(response_data.json())

通过以上代码可以获取到文件夹下的所有文件,并且把绝对路径加入到request的files中,通过data加入要传入的json参数。

对应的 flask的代码也需要修改,因为requests发送多个图片时只能用以上的方式添加,即:

(filename,filepath,filetype),(filename,filepath,filetype)\]在元组内说明文件名,路径,类型,但是这样的话就无法通过键来遍历所有图,所以我就只能通过遍历的方式进行设置了。不过遍历所有文件的方式对于postman发来的所有文件又处理不了,只能找到其发来的第一个文件,所以就只能用两种方式来进行写代码了。 ```python @camunda_power_bp.route('/repair/receipt/', methods=['POST']) @format_func.json_none_blank def repair_receipt(): data = request.form.to_dict() print(data,type(data)) if not isinstance(data,dict): try: data = json.loads(data) except Exception as e: print(e) message = {"code":1,"message":"参数不是json"} return json.dumps(message,ensure_ascii=False) print(request.form) #data = json.loads(data) images = request.files # print(request.files) if images: image_addr_list = image_func.image_save(images,request) #image_addr_list = image_func.image_save_form("file_imgs",request) print(image_addr_list) else: image_addr_list = [] def image_save(images, request): image_addr = [] for img_name in images: # file_list.append(img) imgs = request.files.getlist(img_name) for img in imgs: filename = secure_filename(img.filename) print(filename) img.save(os.path.join(UPLOAD_PATH, filename)) image_addr.append(os.path.join(UPLOAD_PATH, filename)) return image_addr ``` 经过这样的操作,可以对文件和json进行获取。实际使用中,前端使用vue发出的文件请求也是使用本节的方法进行接收的。 ### 4.postgresql保存图片格式数据 在 PostgreSQL 中,你可以使用 bytea 数据类型来存储图片。bytea 是一种用于存储二进制数据的类型,非常适合用于存储图片、音频和视频等文件。 以下是在 PostgreSQL 中存储图片的一般步骤: 创建一个包含 bytea 类型列的表: ```sql CREATE TABLE images ( id SERIAL PRIMARY KEY, image_name VARCHAR(255), image_data BYTEA ); ``` 将图片文件转换为二进制格式: 你可以使用任何编程语言将图片文件转换为二进制格式。例如,在 Python 中,你可以使用以下代码将图片文件转换为二进制格式: ```python with open('image.jpg', 'rb') as file: binary_data = file.read() ``` 将二进制数据插入到 bytea 列中: 使用 SQL 语句将二进制数据插入到 bytea 列中。例如,在 Python 中,你可以使用以下代码将二进制数据插入到 PostgreSQL 数据库中: ```python import psycopg2 conn = psycopg2.connect(database="your_database", user="your_username", password="your_password", host="localhost", port="5432") cur = conn.cursor() with open('image.jpg', 'rb') as file: binary_data = file.read() cur.execute("INSERT INTO images (image_name, image_data) VALUES (%s, %s)", ('image.jpg', binary_data)) conn.commit() cur.close() conn.close() ``` 请注意,上述代码仅提供了一个示例,你需要根据你的实际情况进行修改。确保将 your_database、your_username、your_password、localhost 和 5432 替换为你的实际数据库连接信息。 不过实际使用中,这样的insert还是只能这样用,当我定义sql="INSERT INTO images (image_name, image_data) VALUES (%s, %s)", ('image.jpg', binary_data) 后执行cur.execute(sql)时就出现问题了。同理线程池中也是这样的问题,具体原因有待查询。 参考文献: [postman模拟发送图片:](https://blog.csdn.net/sinat_18866031/article/details/123115472)

相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试