如何在Flask Marshmallow中校验fields.Raw类型的文件上传字段
你拿到值为[object File]的字符串,是因为 Marshmallow 默认仅读取请求的普通表单字段(request.form)进行校验,而上传的文件对象实际存储在 Flask 的 request.files 字典中,没有被传入Schema的校验流程。Swagger UI提交文件时会在普通表单域填充该占位字符串,真实文件并未传递到你写的校验器中。
解决方案
步骤1:校验时传入文件对象
在视图函数调用Schema校验前,手动合并普通表单数据和文件数据:
from flask import request @app.route('/upload', methods=['POST']) def upload(): # 合并表单数据和文件数据传入Schema校验 data = {**request.form, **request.files} errors = UploadRequestSchema().validate(data) if errors: return {"errors": errors}, 400 # 后续业务逻辑
步骤2:编写正确的PNG文件校验器
直接对拿到的文件对象做校验,同时校验文件名后缀和MIME类型,避免篡改后缀的非法文件:
from marshmallow import Schema, fields, Validator, ValidationError from werkzeug.datastructures import FileStorage class PngFileValidator(Validator): def __call__(self, value: FileStorage, **kwargs): # 先判断传入的是不是文件对象 if not isinstance(value, FileStorage): raise ValidationError("必须上传文件") # 校验文件名后缀 filename = value.filename.lower() if not filename.endswith('.png'): raise ValidationError("仅支持png格式的图片") # 可选:校验MIME类型安全性更高 if value.mimetype not in ['image/png', 'image/x-png']: raise ValidationError("文件内容不符合png格式要求")
步骤3:修改Schema并标注Swagger文档
给字段添加Swagger相关的metadata,让生成的文档明确标注仅接受png格式文件:
class UploadRequestSchema(Schema): image = fields.Raw( type="file", validate=PngFileValidator(), required=True, metadata={ "description": "仅支持png格式图片", "format": "binary", "accept": "image/png" } )
如果你使用的是Flask-APISpec 0.39及以上版本,还可以给Schema添加@apispec.schema装饰器,指定请求consumes为multipart/form-data,确保Swagger文档正确识别文件上传请求。
内容的提问来源于stack exchange,提问作者Tran Lan Anh Phan
相关产品推荐
相关产品推荐

