React上传图片至Django后端及PUT请求更新图片失败求助
问题:PUT请求更新图片失败,始终返回旧图片
尝试向Django后端发起PUT请求更新用户头像,但每次返回的都是数据库中已存在的旧图片,新上传的图片并未完成更新,控制台显示的图片信息与实际上传的不一致。
相关代码
views.py
@api_view(['PUT']) def UserPageCreateView(request, pk): if request.method == "PUT": page = UserPage.objects.get(id=pk) serializer = UserPageSerializer(instance=page, data=request.data, many=False, partial="True") if serializer.is_valid(): serializer.save() return Response(serializer.data)
models.py
class UserPage(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) slug = models.SlugField() title = models.CharField(max_length=100, default="") description = models.TextField(max_length=100, default="") profile_photo = models.ImageField(upload_to="images", default="media/images/apple_atgqt1") def save(self, *args, **kwargs): self.slug = self.user.username super().save(*args, **kwargs) def __str__(self): return self.user.username def get_absolute_url(self): return reverse("page_detail", kwargs={"slug": self.slug})
serializers.py
class UserPageSerializer(serializers.ModelSerializer): class Meta: model = UserPage fields = '__all__'
React Fetch请求代码
const PageUpdate = async (e) => { const response = await fetch(`http://127.0.0.1:8000/page-create/${id}`,{ method: "PUT", credentials: "include", headers: { "Content-Type": "multipart/form-data" }, body:JSON.stringify({ "profile_photo": profile_photo, }) }) let data = await response.json() console.log(data) }
图片选择模态框代码
<Modal.Body> <Form> <Form.Group className="mb-3" controlId="exampleForm.ControlInput1"> <Form.Label>Email address</Form.Label> <Form.Control type="file" value={profile_photo} onChange={(e) => setProfilePhoto(e.target.value)} /> </Form.Group> <Form.Group className="mb-3" controlId="exampleForm.ControlTextarea1" > </Form.Group> <Button variant="secondary" onClick={handleClose}> Cancel </Button> </Form> </Modal.Body>
问题分析与修复方案
前端核心问题与修复
- 文件对象获取错误:
e.target.value仅返回文件路径字符串,无法作为文件上传。需改为获取文件对象:onChange={(e) => setProfilePhoto(e.target.files[0])} - 请求格式错误:不能用
JSON.stringify处理文件上传,必须使用FormData封装数据,且无需手动设置Content-Type(浏览器会自动添加正确的边界标识):const PageUpdate = async (e) => { const formData = new FormData(); formData.append('profile_photo', profile_photo); const response = await fetch(`http://127.0.0.1:8000/page-create/${id}`, { method: "PUT", credentials: "include", body: formData }) let data = await response.json() console.log(data) }
后端核心问题与修复
- 视图逻辑漏洞:
serializer定义在PUT判断块内,非PUT请求会导致未定义错误;partial参数需传布尔值True而非字符串"True"。 - 未处理序列化错误:需在验证失败时返回错误信息,便于排查问题。
修复后的views.py:
from rest_framework import status @api_view(['PUT']) def UserPageCreateView(request, pk): page = UserPage.objects.get(id=pk) serializer = UserPageSerializer(instance=page, data=request.data, many=False, partial=True) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
额外配置检查
确保Django项目正确配置媒体文件:
- 在
settings.py中添加:MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') - 在根路由中添加媒体文件访问路由:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 其他路由 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
内容的提问来源于stack exchange,提问作者Khal Shaphat
相关产品推荐
相关产品推荐

