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

如何用React Native向Django服务器上传含图片的表单?

问题修复方案

核心问题:你当前通过JSON传递图片本地路径,但Django的ImageField要求接收**multipart/form-data格式的二进制文件**,而非字符串路径。以下是前后端的具体修复步骤:


一、前端React Native代码修改

1. 重构请求体为FormData

将普通字段和图片文件统一用FormData包裹,图片需以二进制资源形式添加,复杂JSON结构转为字符串传递:

const { Name, bio, displayFilePath, backgroundFilePath } = this.props.route.params.stepOneData;

// 提取ImagePicker返回的图片核心信息
const displayAsset = displayFilePath.assets[0];
const backgroundAsset = backgroundFilePath.assets[0];

// 处理Android端file://前缀,转为本地真实路径
const getLocalFilePath = (uri) => {
  return uri.startsWith('file://') ? uri.slice(7) : uri;
};

const formData = new FormData();

// 添加details下的文本字段
formData.append('details[name]', Name);
formData.append('details[description]', bio);

// 添加display图片文件
formData.append('details[display]', {
  uri: getLocalFilePath(displayAsset.uri),
  name: displayAsset.fileName,
  type: displayAsset.type || 'image/jpeg', // 兜底设置图片MIME类型
});

// 添加background图片文件
formData.append('details[background]', {
  uri: getLocalFilePath(backgroundAsset.uri),
  name: backgroundAsset.fileName,
  type: backgroundAsset.type || 'image/jpeg',
});

// 处理hours数组(复杂结构转为JSON字符串)
formData.append('hours', JSON.stringify([
  {
    "partition":"P1",
    "timings":[{
      "day":"Monday",
      "full_day":false,
      "close_day":false,
      "start_time":"2022-09-16T01:00:00.149Z",
      "close_time":"2022-09-16T01:00:00.149Z"
    }]
  }
]));

try {
  await addNewGroundAPI(formData);
  alert("Post created");
} catch (e) {
  console.log("Error", e);
}

2. 调整API请求配置

不要手动设置Content-Type,让请求库自动生成带boundary的multipart/form-data头(以axios为例):

const addNewGroundAPI = async (formData) => {
  return await axios.post('/api/grounds/', formData, {
    headers: {
      // 注释手动设置,axios会自动处理FormData的请求头
      // 'Content-Type': 'multipart/form-data',
    },
  });
};

二、后端Django代码调整

1. 序列化器适配

确保序列化器的文件字段为ImageField,并支持嵌套结构解析:

from rest_framework import serializers

class TimingsSerializer(serializers.Serializer):
    day = serializers.CharField()
    full_day = serializers.BooleanField()
    close_day = serializers.BooleanField()
    start_time = serializers.DateTimeField()
    close_time = serializers.DateTimeField()

class HoursSerializer(serializers.Serializer):
    partition = serializers.CharField()
    timings = TimingsSerializer(many=True)

class DetailsSerializer(serializers.Serializer):
    name = serializers.CharField()
    description = serializers.CharField()
    display = serializers.ImageField()
    background = serializers.ImageField()

class GroundSerializer(serializers.Serializer):
    details = DetailsSerializer()
    hours = HoursSerializer(many=True)

2. 视图层解析FormData

手动解析JSON字符串字段,构建序列化器所需的数据结构:

from rest_framework.views import APIView
from rest_framework.response import Response
import json

class AddGroundView(APIView):
    def post(self, request):
        try:
            # 解析hours的JSON字符串
            hours_data = json.loads(request.data.get('hours'))
            # 组装完整请求数据
            payload = {
                'details': {
                    'name': request.data['details[name]'],
                    'description': request.data['details[description]'],
                    'display': request.data['details[display]'],
                    'background': request.data['details[background]'],
                },
                'hours': hours_data
            }
            
            serializer = GroundSerializer(data=payload)
            if serializer.is_valid():
                # 此处添加模型保存逻辑,示例:
                # Ground.objects.create(
                #     name=payload['details']['name'],
                #     description=payload['details']['description'],
                #     display=payload['details']['display'],
                #     background=payload['details']['background']
                # )
                return Response({'status': 'success'}, status=201)
            return Response(serializer.errors, status=400)
        except json.JSONDecodeError:
            return Response({'error': 'Invalid hours data'}, status=400)

3. 基础配置检查

确保Django开启文件上传支持:

# settings.py
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:10:33