React Native向Django传图触发MultiValueDictKeyError问题求助
React Native上传图片到Django出现MultiValueDictKeyError问题解决
问题分析
你遇到的MultiValueDictKeyError: 'profileImage'错误核心原因有三点:
- 前端fetch请求错误地将FormData包裹在普通对象中传递,导致后端无法识别表单字段
- 后端误用
request.POST获取上传文件,文件类型表单数据需通过request.FILES读取 - 前端请求缺少适配文件上传的基础配置,未正确传递表单数据
前端代码修改
修复FormData传递与请求逻辑
const [sentI, setSentI] = useState(null); const [profileImage, setProfileImage] = useState(null); // 补充你可能省略的state声明 const sendI = (image) => { const formData = new FormData(); // 用const声明变量避免全局污染 const image_data = { uri: image.uri, name: "profileImage.jpg", // 文件名带后缀,方便后端识别文件类型 type: 'image/jpeg' }; if (image) { formData.append('profileImage', image_data); setSentI(formData); console.log('图片已加入FormData'); } }; const showImagePicker = async () => { const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permissionResult.granted) { alert("你拒绝了应用访问相册的权限!"); return; } const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.cancelled) { setProfileImage(result); sendI(result); } }; const uploadImage = () => { if (!sentI) return; // 确保FormData存在再发起请求 fetch(`http://192.168.5.234:8000/home/imagetest/`, { method: 'POST', body: sentI, // 直接传递FormData,不要包裹在对象内 // 无需手动设置Content-Type,FormData会自动生成multipart/form-data请求头 headers: { // 生产环境需添加CSRF令牌,比如从cookie中获取: // 'X-CSRFToken': document.cookie.split('; ').find(row => row.startsWith('csrftoken=')).split('=')[1] } }) .then(res => res.json()) .then(res => console.log('上传结果:', res)) .catch(error => console.error('上传失败:', error)); }; // 需在页面中添加触发上传的按钮: // <Button onPress={uploadImage} title="上传图片" />
后端代码修改
正确获取文件并保存到模型
假设你有如下模型:
from django.db import models class UserProfile(models.Model): profile_image = models.ImageField(upload_to='profile_images/', blank=True, null=True)
修改视图函数:
from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from .models import UserProfile # 导入你的模型 @csrf_exempt def imagetest(request): if request.method == "POST": # 从request.FILES中获取上传的文件 image_file = request.FILES.get('profileImage') if image_file: # 保存到模型示例 profile = UserProfile.objects.create(profile_image=image_file) profile.save() return JsonResponse({'status': 'success', 'message': '图片上传成功'}) else: return JsonResponse({'status': 'error', 'message': '未获取到图片文件'}, status=400) return JsonResponse({'status': 'error', 'message': '仅支持POST请求'}, status=405)
额外注意事项
- 确保Django配置中
MEDIA_ROOT和MEDIA_URL设置正确,保证图片能正常保存和访问 - 模拟器测试时,确认Django服务IP在模拟器可访问的网络范围内
- 生产环境禁止使用
@csrf_exempt,需通过CSRF令牌验证请求合法性
内容的提问来源于stack exchange,提问作者Itay Lador
相关产品推荐
相关产品推荐

