You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:45:32