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

如何从React Native向Django上传图片并传输多字段表单数据

要实现把表单数据、图片、姓名邮箱传到Django后端,分前端React Native和后端Django两部分来搞:

前端React Native实现步骤

1. 安装图片选择依赖

用react-native-image-picker实现图片选择,执行安装命令:

npm install react-native-image-picker --save
# 或用yarn
yarn add react-native-image-picker

然后配置平台权限:

  • iOS:在Info.plist添加相册/相机权限:
    <key>NSPhotoLibraryUsageDescription</key>
    <string>需要访问相册选择图片</string>
    <key>NSCameraUsageDescription</key>
    <string>需要访问相机拍摄图片</string>
    
  • Android:在AndroidManifest.xml添加权限:
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    

2. 补全组件状态与UI

在你的add_post组件里补充姓名、邮箱、图片状态,添加对应输入框和操作按钮:

import React, { useState } from 'react';
import { View, Text, ScrollView, StyleSheet, ImageBackground, TouchableOpacity } from 'react-native';
import { TextInput } from 'react-native-paper';
import { launchImageLibrary } from 'react-native-image-picker';

const add_post = () => {
  // 原有状态
  const [city, setcity] = useState('');
  const [carinfo, setcarinfo] = useState('');
  const [milage, setmilage] = useState('');
  const [price, setprice] = useState('');
  const [company, setcompany] = useState('');
  // 新增状态
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [selectedImages, setSelectedImages] = useState([]);

  // 图片选择逻辑
  const pickImages = () => {
    const options = {
      mediaType: 'photo',
      maxWidth: 1000,
      maxHeight: 1000,
      quality: 0.8,
      selectionLimit: 5, // 最多选5张,可调整
    };

    launchImageLibrary(options, (response) => {
      if (response.didCancel) return;
      if (response.errorCode) {
        console.log('图片选择出错:', response.errorMessage);
        return;
      }
      setSelectedImages([...selectedImages, ...response.assets]);
    });
  };

  // 提交数据逻辑
  const submitData = async () => {
    const formData = new FormData();

    // 追加表单字段
    formData.append('name', name);
    formData.append('email', email);
    formData.append('city', city);
    formData.append('car_info', carinfo);
    formData.append('milage', milage);
    formData.append('price', price);
    formData.append('company', company);

    // 追加图片,后端用数组接收,字段名带[]
    selectedImages.forEach((image, index) => {
      formData.append('images[]', {
        uri: image.uri,
        type: image.type,
        name: `car_image_${index}.jpg`,
      });
    });

    try {
      const response = await fetch('http://你的Django服务器IP:端口/api/car-post/', {
        method: 'POST',
        body: formData,
        // fetch会自动处理multipart/form-data的Content-Type,无需手动设置
      });

      if (response.ok) {
        const result = await response.json();
        console.log('提交成功:', result);
        // 可添加清空表单等后续逻辑
      } else {
        const error = await response.json();
        console.log('提交失败:', error);
      }
    } catch (err) {
      console.log('网络错误:', err);
    }
  };

  return (
    <ScrollView>
      {/* 保留你原有的步骤指示器代码 */}
      <ImageBackground>
        {/* ... 你的原有代码 ... */}
      </ImageBackground>

      <View style={{backgroundColor:'green', width:'100%', marginTop:120, paddingBottom:20}}>
        <Text style={{alignSelf:'center', fontSize:25, color:'white', marginVertical:10}}>
            Car Information
        </Text>
        {/* 新增姓名输入框 */}
        <TextInput
          style={styles.inputstyle}
          label="姓名"
          value={name}
          mode="outlined"
          onChangeText={Text => setName(Text)}
        />
        {/* 新增邮箱输入框 */}
        <TextInput
          style={styles.inputstyle}
          label="邮箱"
          value={email}
          mode="outlined"
          onChangeText={Text => setEmail(Text)}
        />
        {/* 原有输入框,保留 */}
        <TextInput
          style={styles.inputstyle}
          label="City"
          value={city}
          mode="outlined"
          onChangeText={Text => setcity(Text)}
        />
        <TextInput
          style={styles.inputstyle}
          label="Car Information"
          value={carinfo}
          mode="outlined"
          onChangeText={Text => setcarinfo(Text)}
        />
        <TextInput
          style={styles.inputstyle}
          label="Milage"
          value={milage}
          mode="outlined"
          onChangeText={Text => setmilage(Text)}
        />
        <TextInput
          style={styles.inputstyle}
          label="Price"
          value={price}
          mode="outlined"
          onChangeText={Text => setprice(Text)}
        />
        <TextInput
          style={styles.inputstyle}
          label="Company"
          value={company}
          mode="outlined"
          onChangeText={Text => setcompany(Text)}
        />

        {/* 图片选择按钮 */}
        <TouchableOpacity
          style={{
            backgroundColor: '#fff',
            padding: 10,
            borderRadius: 5,
            alignSelf: 'center',
            marginVertical: 15,
          }}
          onPress={pickImages}
        >
          <Text style={{color: 'green', fontSize: 16}}>选择图片</Text>
        </TouchableOpacity>

        {/* 提交按钮 */}
        <TouchableOpacity
          style={{
            backgroundColor: '#fff',
            padding: 15,
            borderRadius: 5,
            alignSelf: 'center',
            width: '80%',
          }}
          onPress={submitData}
        >
          <Text style={{color: 'green', fontSize: 18, textAlign: 'center'}}>提交信息</Text>
        </TouchableOpacity>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  inputstyle:{
    marginTop:15,
    width:200,
    alignSelf:'center',
  }
});

export default add_post;
后端Django实现步骤

1. 配置媒体文件与跨域

先安装跨域处理包:

pip install django-cors-headers

在settings.py中配置:

INSTALLED_APPS = [
    # ... 其他内置app
    'corsheaders',
    'rest_framework',
]

MIDDLEWARE = [
    # ... 其他中间件
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
]

# 允许跨域的源,根据RN调试地址调整
CORS_ALLOWED_ORIGINS = [
    "http://localhost:8081",
    "http://192.168.x.x:8081", # 真机调试的本地IP
]

# 媒体文件存储配置
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'

在项目根目录urls.py挂载媒体路由:

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('你的app名称.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

2. 创建数据模型

在你的app的models.py中定义模型:

from django.db import models

class CarPost(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()
    city = models.CharField(max_length=100)
    car_info = models.TextField()
    milage = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    company = models.CharField(max_length=100)
    images = models.ManyToManyField('CarImage', related_name='car_posts')

class CarImage(models.Model):
    image = models.ImageField(upload_to='car_images/%Y/%m/%d/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

执行数据库迁移:

python manage.py makemigrations
python manage.py migrate

3. 编写接收请求的视图

在app的views.py中编写视图:

from django.http import JsonResponse
from rest_framework.decorators import api_view
from .models import CarPost, CarImage
from django.core.files.uploadedfile import UploadedFile

@api_view(['POST'])
def create_car_post(request):
    try:
        # 提取表单数据
        name = request.data.get('name')
        email = request.data.get('email')
        city = request.data.get('city')
        car_info = request.data.get('car_info')
        milage = request.data.get('milage')
        price = request.data.get('price')
        company = request.data.get('company')

        # 创建汽车帖子实例
        car_post = CarPost.objects.create(
            name=name,
            email=email,
            city=city,
            car_info=car_info,
            milage=milage,
            price=price,
            company=company
        )

        # 处理上传的图片
        images = request.FILES.getlist('images[]')
        for image in images:
            if isinstance(image, UploadedFile):
                car_image = CarImage.objects.create(image=image)
                car_post.images.add(car_image)

        return JsonResponse({
            'status': 'success',
            'message': '汽车信息提交成功',
            'data': {'id': car_post.id, 'name': car_post.name}
        }, status=201)

    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': str(e)
        }, status=400)

4. 配置路由

在app目录下新建urls.py,配置路由:

from django.urls import path
from .views import create_car_post

urlpatterns = [
    path('car-post/', create_car_post, name='create_car_post'),
]

最后启动Django服务器,确保RN和Django在同一局域网内(真机调试时),即可测试提交功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:55:23