Django3.1+Vue3通过POST API上传图片时图片字段为空,如何解决?
问题描述
我正在开发一个以Django 3.1为后端、Vue 3为前端的项目,刚接触Django仍在学习阶段,不确定当前实现是否正确。
我创建了包含用户邮箱和图片字段的模型:
class UsedBike(models.Model): sellerEmail = models.CharField(max_length=255) image = models.ImageField(upload_to='uploads/', blank=True, null=True) class Meta: ordering = ('sellerEmail', ) def __str__(self): return self.sellerEmail def get_image(self): if self.image: return 'http://127.0.0.1:8000' + self.image.url return ''
序列化器代码:
class UsedBikeSerializer(serializers.ModelSerializer): class Meta: model = UsedBike fields = ( "id", "sellerEmail", "get_image", )
视图保存函数:
@api_view(['POST']) def sellBike(request): serializer = UsedBikeSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data)
前端Vue的请求代码:
submitData() { const formData = { sellerEmail: this.sellerEmail, image: this.productImage } axios .post("/api/v1/sell-bike/", formData) .then(response => { console.log(response) }).catch(error => { console.log(error) }) },
模板控件:
<input type="text" v-model="sellerEmail"> <input type="file" accept="image/png, image/jpeg" id="imageInput" v-on:change="onFileChange()"> <button @click="submitData">Upload</button>
文件选择方法:
onFileChange(e) { let imageInput = document.getElementById("imageInput") this.productImage = imageInput.files[0] },
发送请求后,Django终端返回"POST /api/v1/sell-bike/ HTTP/1.1" 200 55,但打印request.data得到{'sellerEmail': 'test@email.com', 'image': {}},数据库中邮箱已保存,但image字段为空。
解决方案
前端修改:用FormData传递文件
浏览器上传文件必须使用multipart/form-data编码,普通JSON对象无法传递文件,需将数据包装为FormData实例:
submitData() { const formData = new FormData(); formData.append('sellerEmail', this.sellerEmail); if (this.productImage) { formData.append('image', this.productImage); } axios.post("/api/v1/sell-bike/", formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then(response => { console.log(response) }).catch(error => { console.log(error) }) },
后端修改1:序列化器添加image字段
当前序列化器未包含image字段,无法处理上传的文件。需添加该字段,并将自定义方法get_image标记为SerializerMethodField:
from rest_framework import serializers from .models import UsedBike class UsedBikeSerializer(serializers.ModelSerializer): get_image = serializers.SerializerMethodField() class Meta: model = UsedBike fields = ( "id", "sellerEmail", "image", # 新增字段用于接收上传文件 "get_image", ) def get_image(self, obj): if obj.image: return 'http://127.0.0.1:8000' + obj.image.url return ''
后端修改2:完善视图错误反馈
在视图中返回验证错误信息,方便调试,并使用正确的状态码:
from rest_framework.decorators import api_view from rest_framework.response import Response from .serializers import UsedBikeSerializer @api_view(['POST']) def sellBike(request): serializer = UsedBikeSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) # 创建成功返回201状态码 return Response(serializer.errors, status=400) # 验证失败返回错误详情
额外配置:媒体文件路径设置
在settings.py中配置媒体文件的存储路径和访问URL:
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
在项目根urls.py中添加媒体文件路由:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 你的其他URL配置 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
配置完成后,上传的图片会存储在media/uploads/目录下,可通过http://127.0.0.1:8000/media/uploads/xxx.jpg访问。
内容的提问来源于stack exchange,提问作者Nom
相关产品推荐
相关产品推荐

