使用formdata在vue和django之间传递文件

在前端页面中如果有文件或者图片需要上传的场景下,通用做法是使用formdata将文件从前端传输到后台,在后台上传文件并将url保存在数据库。
当前项目是使用vue + Element UI + django 的框架,需要将文件从vue传递到django中,上传阿里云OSS存储。记录使用方法

formdata的简单使用

创建

新建一个formdata的变量

var data = new FormData() 
    data.append('name', this.createForm.name)
    data.append('desc', this.createForm.desc)
    data.append('page_url', this.createForm.page_url)
    data.append('edit', this.createForm.edit)
    data.append('page_id', this.createForm.page_id)

添加数据

通过append(key, value)来添加数据,这里分为两种情况,
一、key值无重复
key值不存在重复的情况下,一个key对应一个value

data.append('name', this.createForm.name)
data.append('desc', this.createForm.desc)

二、key值重复
key值在某些时候会重复,如上传多个文件时,这时一个key对应一个数组,数组中为多个value

data.append('file', file.raw)
data.append('file', file.raw)

获取数据

key值对应一个value,可以通过get方法取值

data.get(key)

key值对应多个value,可以通过getAll方法取值

data.getAll(key)

如果key对应多个value而使用get取值,只能取到value的最后一个值

判断数据是否存在

我们可以通过has(key)来判断是否对应的key值

data.has('name')

删除数据

通过delete(key),来删除数据

data.delete('name')

遍历数据

我们可以通过entries()来获取一个迭代器,然后遍历所有的数据,

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k2", "v1");
 
var i = formData.entries();
 
i.next(); // {done:false, value:["k1", "v1"]}
i.next(); // {done:fase, value:["k1", "v2"]}
i.next(); // {done:fase, value:["k2", "v1"]}
i.next(); // {done:true, value:undefined}

项目中使用

要完成的功能如下,在一个弹出框中能够输入信息,重点是能够添加多个文件。

Element UI中已经处理好,当选择多个文件之后,会保存到一个数组中,我只需要对这个数组操作即可。

vue代码

创建formdata

var data = new FormData();
// 普通变量
data.append('name', this.createForm.name)
data.append('desc', this.createForm.desc)
data.append('page_url', this.createForm.page_url)
data.append('edit', this.createForm.edit)
data.append('page_id', this.createForm.page_id)

// 文件。因为涉及到编辑功能,所以对于新上传的文件保存其`file.raw`,编辑的文件保存文件id
this.createForm.file.forEach((file) => {
  if (file.raw) {
    data.append('new_files', file.raw)
  }else{
    data.append('old_files', file.page_file_id)
  }
})
pageCreate(data).then((res) => {
........
}
}

发送请求

export function pageCreate(form) {
    return postForm(URL.createUrl, form)
}

post请求的内容格式。post请求不是普通的json而是form-data

export function postForm (url, data= {}) {
  return new Promise((resolve, reject) => {
    axios.create({
      withCredentials: true,
      headers: {'X-CSRFToken': getCookie('csrftoken'), 'Content-Type':  "multipart/form-data"},
    }).post(url, data).then(response => {
      resolve(response.data)
    }, err => {
      reject(err)
    })
  })
}

后端处理

django的接收:

# 接收到formdata的出文件之外的数据
data = request.POST

# 接收文件,getlist是接收多个文件
# formdata在vue中同一个key传入了多个value,value成为了一个数组,所以需要使用getlist来获取所有文件
new_files = request.FILES.getlist('new_files')


# formdata在vue中同一个key只有一个文件类型的value,可以使用get来获取文件
new_files = request.FILES.get('file')

后续将文件上传到阿里云的对象存储,将文件的url保存到数据库。展示或编辑文件时,只需要传入文件的url,element UI即可解析出文件。

posted @ 2021-06-15 16:42  金色旭光  阅读(2490)  评论(0编辑  收藏  举报