Django REST Framework多图片上传问题:仅保存最后一张图片
Django REST Framework 多图片上传问题解决方法
问题根源
你的代码中,ReviewImages实例的创建语句rev = ReviewImages()放在了for循环外部,每次循环只是修改同一个实例的images字段并保存,相当于持续更新同一条数据库记录,最终只有最后一张图片被保留。
修复步骤
1. 修正视图的图片保存逻辑
将ReviewImages实例的创建移至循环内部,确保每张图片对应一条独立的数据库记录:
class SubmitReview(APIView): permission_classes = [IsAuthenticated] def post(self, request, product_slug): data = request.data # 补充获取product对象的逻辑(原代码缺失该变量定义) product = Products.objects.get(slug=product_slug) # 完善空内容校验逻辑 if not data.get("rating") and not data.get("review"): return Response({"error": "评分或评价内容至少填写一项"}, status=status.HTTP_400_BAD_REQUEST) review = ReviewRatings.objects.create( user=request.user, product=product, rating=data["rating"], review=data["review"], ) review_images = request.FILES.getlist('review_images') # 循环内创建新实例,每张图片对应一条记录 for image in review_images: rev = ReviewImages() rev.review = review rev.images = image rev.save() serializer = ReviewSerializer(review, context={'request':request}) return Response(serializer.data, status=status.HTTP_201_CREATED)
2. 可选:通过序列化器统一处理关联数据
如果想让序列化器承担关联图片的创建逻辑,简化视图代码,可以修改ReviewSerializer添加create方法:
class ReviewSerializer(ModelSerializer): user = SerializerMethodField() review_images = ReviewImagesSerializer(many=True, required=False) class Meta: model = ReviewRatings fields = [ "user", "rating", "review", "created_at", "updated_at", "review_images", ] def get_user(self, obj): return f"{obj.user.first_name} {obj.user.last_name}" def create(self, validated_data): # 取出嵌套的图片数据 images_data = validated_data.pop('review_images', []) # 创建主评价记录 review = ReviewRatings.objects.create(**validated_data) # 批量创建图片关联记录 for image_data in images_data: ReviewImages.objects.create(review=review, **image_data) return review
对应的视图可以简化为:
class SubmitReview(APIView): permission_classes = [IsAuthenticated] def post(self, request, product_slug): data = request.data product = Products.objects.get(slug=product_slug) # 补充关联对象ID到请求数据 data['user'] = request.user.id data['product'] = product.id serializer = ReviewSerializer(data=data, context={'request': request}) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
注:这种方式需要前端将图片数据以嵌套数组格式提交,比如使用
review_images[0][images]这类键名传递多图数据。
验证效果
修改完成后,上传多张图片时,每张图片都会生成独立的ReviewImages记录,序列化响应会包含所有图片的URL列表,与你期望的输出格式一致。
内容的提问来源于stack exchange,提问作者Sins97
相关产品推荐
相关产品推荐

