如何在Django REST Framework(DRF)中实现多图片上传
Django REST Framework 多图片上传实现方案
要实现商品关联多图片上传,且GET请求返回图片URL列表,需对现有代码做以下调整:
1. 修改模型结构
单ImageField无法存储多张图片,需拆分出独立的图片模型与商品关联:
# models.py from django.db import models from django.utils.translation import gettext_lazy as _ # 保留你原有的文件路径生成函数 def get_file_path(instance, filename): # 示例:按商品ID生成存储目录 return f"goods/{instance.goods.id}/{filename}" class sellGoods(models.Model): goods_name = models.CharField(verbose_name=_('物品名称'), max_length=90) # 保留你原有的其他属性(如用户关联等) class GoodsImage(models.Model): # 与商品关联,related_name用于反向查询图片列表 goods = models.ForeignKey(sellGoods, on_delete=models.CASCADE, related_name='images') img = models.ImageField(upload_to=get_file_path, verbose_name='图片', null=True, blank=True)
2. 调整序列化器
嵌套序列化图片模型,实现GET请求返回图片URL列表,同时支持商品信息序列化:
# serializers.py from rest_framework import serializers from .models import sellGoods, GoodsImage class GoodsImageSerializer(serializers.ModelSerializer): # use_url=True 自动生成图片的访问URL img = serializers.ImageField(use_url=True) class Meta: model = GoodsImage fields = ('img',) class sellSerializer(serializers.ModelSerializer): # 关联图片列表,many=True表示多实例,read_only=True仅用于序列化输出 images = GoodsImageSerializer(many=True, read_only=True) class Meta: model = sellGoods # 按需添加商品的其他字段 fields = ('id', 'goods_name', 'images',)
3. 重写视图逻辑
处理POST请求时,先保存商品基本信息,再批量保存上传的图片:
# views.py from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import sellGoods, GoodsImage from .serializers import sellSerializer class sellGoodsList(APIView): def post(self, request, format=None): # 分离商品基本数据和图片文件 goods_data = {k: v for k, v in request.data.items() if k != 'images'} serializer = sellSerializer(data=goods_data) if serializer.is_valid(): # 保存商品实例 goods = serializer.save() # 获取上传的多张图片(request.FILES.getlist用于批量获取同名字段的文件) images = request.FILES.getlist('images') # 批量创建图片关联记录 for img in images: GoodsImage.objects.create(goods=goods, img=img) # 返回包含图片列表的商品完整数据 return Response(sellSerializer(goods).data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def get(self, request, format=None): # 列表查询时自动返回每个商品的图片URL列表 goods_list = sellGoods.objects.all() serializer = sellSerializer(goods_list, many=True) return Response(serializer.data)
4. Postman测试说明
- 请求方式选择
POST,无需手动设置Content-Type,Postman会自动处理multipart/form-data - 表单字段中:
- 填写商品的基本属性(如
goods_name) - 图片字段名设为
images,点击"Add Files"选择多张图片(可多次添加同一个images字段上传多文件)
- 填写商品的基本属性(如
- 发送请求后,返回数据中
images字段为图片URL列表
内容的提问来源于stack exchange,提问作者胡侃有料
相关产品推荐
相关产品推荐

