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

Django无表单多图上传问题:单图正常,多图无法接收需如何修改?

嘿,我来给你梳理两种实用的Django多图上传实现方案,都是基于你现有的代码改造的,你可以根据自己的场景选择:

方案一:一对多关联模型(通用推荐)

这个方案适配所有数据库类型,而且扩展性极强——以后要是想给单张图片加标题、排序权重、描述之类的字段,直接在子模型里加就行,非常灵活。

修改 models.py

把原来的单图字段拆分成两个关联模型:一个父模型Upload用来记录上传的基础信息,一个子模型Image用来存储单张图片,通过外键关联到Upload:

from django.db import models

class Upload(models.Model):
    # 这里可以添加你需要的其他字段,比如上传时间、上传用户等
    created_at = models.DateTimeField(auto_now_add=True)

class Image(models.Model):
    upload = models.ForeignKey(Upload, on_delete=models.CASCADE, related_name='images')
    image = models.ImageField(upload_to='images/')

备注:related_name='images' 是为了方便从Upload实例直接获取所有关联的图片,比如upload.images.all()就能拿到该上传记录下的所有图片。

修改 serializers.py

需要用嵌套序列化器来处理关联模型的创建,同时重写create方法,手动拆分上传数据:

from rest_framework import serializers
from .models import Upload, Image

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ['image']

class UploadSerializer(serializers.ModelSerializer):
    images = ImageSerializer(many=True)

    class Meta:
        model = Upload
        fields = ['id', 'created_at', 'images']

    def create(self, validated_data):
        # 先提取出图片相关的数据
        images_data = validated_data.pop('images')
        # 创建父模型Upload的实例
        upload = Upload.objects.create(**validated_data)
        # 循环创建每张图片对应的Image实例
        for image_data in images_data:
            Image.objects.create(upload=upload, **image_data)
        return upload

修改 views.py

如果前端用FormData格式上传多文件(最常用的文件上传方式),可以重写create方法直接处理请求中的文件列表,这样前端不用传嵌套的JSON,只需把所有图片放在images字段里即可:

from rest_framework import viewsets, permissions
from rest_framework.response import Response
from .models import Upload, Image
from .serializers import UploadSerializer

class UploadViewSet(viewsets.ModelViewSet):
    queryset = Upload.objects.all()
    permission_classes = [permissions.AllowAny]
    serializer_class = UploadSerializer

    def create(self, request, *args, **kwargs):
        # 从请求中获取所有上传的图片文件
        images = request.FILES.getlist('images')
        # 创建Upload实例
        upload = Upload.objects.create()
        # 批量创建关联的Image实例
        for img in images:
            Image.objects.create(upload=upload, image=img)
        # 返回序列化后的上传记录
        serializer = self.get_serializer(upload)
        return Response(serializer.data, status=201)
方案二:使用ArrayField(仅适用于PostgreSQL数据库)

如果你的项目刚好使用PostgreSQL数据库,也可以用Django提供的ArrayField直接存储多个图片路径,代码改动更小,但扩展性较差(无法给单张图片加额外属性)。

修改 models.py

替换原来的ImageField为ArrayField:

from django.db import models
from django.contrib.postgres.fields import ArrayField

class Upload(models.Model):
    images = ArrayField(models.ImageField(upload_to='images/'), default=list)

修改 serializers.py

用ListField来处理多文件的序列化:

from rest_framework import serializers
from .models import Upload

class UploadSerializer(serializers.ModelSerializer):
    images = serializers.ListField(
        child=serializers.ImageField(max_length=100000, allow_empty_file=False, use_url=True)
    )

    class Meta:
        model = Upload
        fields = '__all__'

修改 views.py

同样需要重写create方法来处理多文件上传:

from rest_framework import viewsets, permissions
from .models import Upload
from .serializers import UploadSerializer

class UploadViewSet(viewsets.ModelViewSet):
    queryset = Upload.objects.all()
    permission_classes = [permissions.AllowAny]
    serializer_class = UploadSerializer

    def create(self, request, *args, **kwargs):
        images = request.FILES.getlist('images')
        upload = Upload.objects.create(images=images)
        serializer = self.get_serializer(upload)
        return Response(serializer.data, status=201)

内容的提问来源于stack exchange,提问作者Titan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:57:47