侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

NaiveUI + Axios + DRF 处理文件上传

barwe
2022-10-31 / 0 评论 / 2 点赞 / 2,678 阅读 / 1,153 字
温馨提示:
本文最后更新于 2023-06-07,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

NaiveUI 提供的 NUpload 组件用来上传文件,这里有个坑:该组件的模型响应变量不是原生的 File 对象,而是在 File 对象外面又套了一层:

// import type { UploadFileInfo } from 'naive-ui'
export interface FileInfo {
    id: string;
    name: string;
    batchId?: string | null;
    percentage?: number | null;
    status: 'pending' | 'uploading' | 'finished' | 'removed' | 'error';
    url?: string | null;
    file?: File | null;
    thumbnailUrl?: string | null;
    type?: string | null;
    fullPath?: string | null;
}

可以看到,模型响应变量的 file 成员才是真正可以添加进 FormData 的文件,直接添加 FileInfo 对象就会导致文件上传失败。

上传文件和其他参数的混合数据只能使用 multipart/form-data 这个类型:

const formData = new FormData()
// 向表单数据对象中添加一个文件,注意需要提取出 file 成员
formData.append('abundanceFile', abd.file as File)
// 向表单数据对象中添加一个普通的参数
formData.append('taskName', 'xxxxxxxx')
// 向表单数据对象中添加一个复杂数据,这里用 JSON 序列化方便服务器解包
formData.append('params', JSON.stringify(params))

在发起请求时别忘了设置 Content-Type:

const r: AxiosResponse = await axios.post('/xxx', formData, {
    headers: { 'Content-Type': 'multipart/form-data' }
})

后端使用 DRF 框架,在 viewset 实例中读取文件内容:

@action(methods=['post'], detail=True, url_path='start')
def start(self, request: Request, pk):
    for k in request.data:
        if k == 'taskName': pass
        elif k == 'params': pass
        else:
            f = request.data.get(k)
            print(f.read().decode('utf-8'))
            with open('module/test.txt', 'wb') as wt:
                wt.write(f.read())
    return Response(1)

也可以使用模型保存。

2

评论区