You need to enable JavaScript to run this app. Flask App Builder带文件字段的ModelRestApi POST上传如何正确调用?
优惠活动
大模型
产品
解决方案
定价
更多

Flask App Builder带文件字段的ModelRestApi POST上传如何正确调用?

Flask-AppBuilder 带文件上传的POST接口正确调用方案

原有调用方式失败的核心问题

  • 参数结构不规范:将普通文本字段description和文件字段一同放入requests.post的files参数中,不符合FAB REST接口对multipart/form-data请求的解析规则
  • 接口配置缺失:未在ModelRestApi中显式声明允许通过POST接口写入的字段,FAB默认会拦截FileColumn这类特殊字段的写入请求
  • 鉴权逻辑不匹配:仅开启allow_browser_login仅支持浏览器端会话鉴权,非浏览器调用需要携带有效的认证Header

服务端接口配置调整(基于现有代码)

在原有FileApi类的基础上补充字段声明配置,不需要额外编写自定义上传逻辑:

class FileApi(ModelRestApi):
    resource_name = "File"
    datamodel = SQLAInterface(Files)
    allow_browser_login = True
    # 显式声明允许通过POST接口新增的字段,必须包含FileColumn对应的file字段
    add_columns = ["file", "description"]
    # 可选:配置文件上传的校验规则
    validators_columns = {
        "file": [
            FileSizeValidator(limit_value=10*1024*1024), # 单文件最大10MB
            FileAllowedExtensions(allowed_extensions=["txt", "pdf", "png"])
        ]
    }

appbuilder.add_api(FileApi)

客户端正确调用示例

修正之前的请求参数结构,按规范传递文件和普通字段:

import requests

# FAB REST接口默认统一前缀为/api/v1,结合你定义的resource_name,完整接口路径为
url = "http://服务地址/api/v1/File"
# 携带有效认证信息,例如通过登录接口获取的JWT Token
headers = {
    "Authorization": "Bearer 你的有效JWT令牌"
}
# 文件参数:需明确指定文件名、文件流、文件类型
files = {
    "file": ("test.txt", open("test.txt", "rb"), "text/plain")
}
# 普通表单字段:独立放入data参数,不要混入files字典
data = {
    "description": "test"
}

response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())

灵活自定义上传的替代方案

如果需要脱离ModelRestApi的自动解析逻辑、自定义存储流程,可以在常规ModelView中实现独立的上传路由:

from flask import request, jsonify
from flask_appbuilder import ModelView, expose

class ProjectFilesModelView(ModelView):
    datamodel = SQLAInterface(Files)

    @expose("/custom_upload", methods=["POST"])
    def custom_upload(self):
        uploaded_file = request.files.get("file")
        desc = request.form.get("description", "")
        if not uploaded_file:
            return jsonify({"msg": "未检测到上传文件"}), 400
        # 自行实现文件存储、数据库写入逻辑
        file_record = Files(
            file=uploaded_file,
            description=desc
        )
        self.datamodel.add(file_record)
        return jsonify({"id": file_record.id, "msg": "上传成功"})

常见踩坑提示

  • 注意:FAB自动解析文件上传的逻辑仅支持multipart/form-data格式的请求,不支持纯JSON格式传递文件内容
  • 确保应用初始化时配置了可读写的APP_MEDIA_FOLDER路径,否则FileColumn会因为无存储权限写入失败
  • 不要在files参数中传入非文件类型的键值对,否则会导致请求体编码异常,触发接口解析失败

内容的提问来源于stack exchange,提问作者Hyoungki Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 00:27:02