You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Axios上传图片至Django API时文件为空的问题求助

解决React + Axios上传图片到Django API时File字段为空的问题

我一眼就揪出了问题的核心:你现在是用JSON格式提交文件数据,但File对象属于二进制类型,JSON根本没法正确序列化它,所以控制台里file字段才会显示为{},再加上请求头设置的Content-Type: application/json完全不适合文件上传场景,这俩问题凑一起就导致图片传不出去了。下面给你一步步捋清楚解决方案:

1. 先修复State更新的小bug

看你的onChange和handleImage方法里,更新state时写的是this.setState({ cats, });,但你的state字段明明是car_photo啊!这会导致你的分类和文件数据根本没存到正确的state位置,先把这两处改成:

await this.setState({ car_photo: cats });

2. 改用FormData构造上传数据

文件上传必须用FormData对象,它是专门用来处理multipart/form-data格式请求体的。修改你的handleSubmit方法:

handleSubmit(e) {
  e.preventDefault();
  
  // 创建FormData实例
  const formData = new FormData();
  
  // 循环把每个图片项的字段加到FormData里
  this.state.car_photo.forEach((photo, index) => {
    formData.append(`car_photo[${index}][category]`, photo.category);
    formData.append(`car_photo[${index}][sub_category]`, photo.sub_category);
    // 只有当file存在时才添加,避免传空值
    if (photo.file) {
      formData.append(`car_photo[${index}][file]`, photo.file);
    }
  });

  axios({
    method: "PUT",
    url: `${config.apiUrl.car}${this.props.match.params.pk}/profile/`,
    headers: {
      Accept: "application/json, application/xml, text/plain, text/html, *.*",
      // 删掉Content-Type: application/json,让Axios自动处理multipart/form-data
      Authorization: "Bearer " + JSON.parse(authToken),
    },
    data: formData, // 这里传FormData而不是普通JSON
  })
  .then((res) => {
    Swal.fire({ 
      title: "Car", 
      type: "success", 
      text: "Car Update Successfully !", 
      showConfirmButton: false, 
      timer: 2000, 
    });
  })
  .catch((err) => {
    Swal.fire({ 
      title: "Car", 
      type: "error", 
      text: "Error while updating new Car!", 
      timer: 2000, 
    });
  });
}

3. Django端的注意事项

因为你用的是PUT请求,Django默认中间件可能不会自动解析PUT请求里的multipart/form-data数据。如果你的视图里拿不到request.FILES,可以试试这两种办法:

  • 业务允许的话改用PATCH请求,Django对PATCH的multipart数据处理更友好
  • 或者在视图里手动适配PUT请求的multipart解析:
from django.http import QueryDict

def your_car_profile_view(request, pk):
    if request.method == 'PUT':
        # 手动解析multipart数据
        if request.content_type.startswith('multipart/form-data'):
            # 直接使用request.POST和request.FILES即可
            form_data = request.POST
            files = request.FILES
        # 后续处理你的业务逻辑...

为什么之前的方式不行?

  • JSON只能序列化字符串、数字、普通对象这类基本类型,File对象是二进制资源,无法被JSON序列化,所以你console.log(data)看到的file是{},这是File对象转JSON后的默认结果
  • 上传文件必须用multipart/form-data格式的请求体,而不是application/json,两者的编码规则完全不同,硬套肯定传不出去

按照上面的步骤修改后,应该就能正常把图片和分类数据一起传到Django API了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:32:44