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

React向Django后端同时发送列表与图片的FormData方案问询

解决React向Django后端同时发送图片与数组数据的问题

你遇到的这个场景太常见了——用FormData传数组会被转成字符串,导致Django DRF认不出是PK列表;直接发普通对象又没法正确处理文件上传。下面给你两种可行的方案,核心思路就是让数据既能满足文件上传的格式要求,又能让Django正确解析数组。

方案一:逐个append数组元素(推荐)

Django的DRF原生支持同一个参数名多次传值来接收数组,所以我们只需要把custom_list里的每个元素单独加到FormData中,而不是直接append整个数组。这样DRF会自动把这些值拼成数组,完美匹配你需要的PK列表类型。

React端修改后的代码:

let formData = new FormData();
formData.append('text', postForm.text);
formData.append('image', postForm.image, postForm.image.name);
formData.append('privacy', postForm.privacy);

// 关键操作:循环数组,把每个PK单独加到同一个key下
postForm.customList.forEach(pk => {
  formData.append('custom_list', pk);
});

props.createPost(formData);

Django端Serializer配置(确保支持数组)

如果你的Serializer用的是PrimaryKeyRelatedField,记得加上many=True来声明这是一个数组:

from rest_framework import serializers
from .models import Post, YourCustomModel # 替换成你的实际模型

class PostSerializer(serializers.ModelSerializer):
    custom_list = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=YourCustomModel.objects.all()
    )

    class Meta:
        model = Post
        fields = ['text', 'image', 'privacy', 'custom_list']

请求注意事项

用axios发送请求时,不用手动设置Content-Type——当你传入FormData实例时,axios会自动把请求头设为multipart/form-data,自动处理文件和表单数据:

const createPost = async (formData) => {
  const response = await axios.post('/api/posts/', formData);
  return response.data;
};

方案二:将数组转为JSON字符串(备选)

如果你不想循环append,也可以把数组转成JSON字符串,后端再解析成数组。不过这种方式需要后端额外处理,不如方案一简洁。

React端代码:

let formData = new FormData();
formData.append('text', postForm.text);
formData.append('image', postForm.image, postForm.image.name);
formData.append('privacy', postForm.privacy);
// 把数组转成JSON字符串后再append
formData.append('custom_list', JSON.stringify(postForm.customList));

Django端处理:

在视图或Serializer里手动解析JSON字符串:

# 视图示例
from django.http import JsonResponse
import json

def create_post(request):
    if request.method == 'POST':
        # 解析JSON字符串为数组
        custom_list = json.loads(request.POST.get('custom_list', '[]'))
        # 其他数据处理逻辑...

或者在Serializer中用ListField直接接收:

from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    custom_list = serializers.ListField(child=serializers.IntegerField())

    class Meta:
        model = Post
        fields = ['text', 'image', 'privacy', 'custom_list']

为什么之前的方法行不通?

  • 直接append数组到FormData:FormData会自动把数组转成逗号分隔的字符串(比如[1,2,3]变成"1,2,3"),DRF会把这个字符串当作单个PK值,自然抛出类型错误。
  • 直接发送普通对象:普通JSON请求无法传递文件(File对象会被序列化成无效格式),所以DRF会提示“提交的数据不是文件”。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:27:50