Vue上传多文件至DRF后端触发AttributeError错误求助
解决DRF多文件上传时的AttributeError问题
这个错误的根源很清晰:你的FilesSerializer.create()方法返回的是File对象的列表,但你用的ModelViewSet默认是为单个模型实例设计的——当视图尝试把返回的列表传给序列化器时,它会去这个列表对象上找files字段,自然就会抛出'list' object has no attribute 'files'的错误。
下面给你两种可行的解决方案,你可以根据自己的需求选择:
方案一:在ModelViewSet中添加自定义多文件上传动作(推荐)
这种方式既保留了ModelViewSet自带的其他功能(比如查询所有文件、删除单个文件等),又新增了专门处理多文件上传的接口:
修改views.py
from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from .models import File from .serializers import FilesSerializer, FileSerializer class FileViewSet(viewsets.ModelViewSet): parser_classes = (FormParser, MultiPartParser) queryset = File.objects.all() serializer_class = FileSerializer # 处理单个File实例的序列化器 # 自定义多文件上传接口,路由对应 /files/upload_multiple/ @action(detail=False, methods=['post']) def upload_multiple(self, request): # 用FilesSerializer处理多文件提交数据 serializer = FilesSerializer(data=request.data) if serializer.is_valid(): file_objs = serializer.save() # 用单个实例序列化器处理返回的文件列表,必须加上many=True response_serializer = FileSerializer(file_objs, many=True) return Response(response_serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
确保serializers.py的命名和逻辑正确
from rest_framework import serializers from .models import File # 单个File实例的序列化器 class FileSerializer(serializers.ModelSerializer): class Meta: model = File fields = ['id', 'file', 'uploaded_at'] # 多文件上传的序列化器 class FilesSerializer(serializers.Serializer): files = serializers.ListField(child=serializers.FileField()) def create(self, validated_data): files = validated_data['files'] file_objs = [File.objects.create(file=file) for file in files] return file_objs
方案二:改用APIView专门处理多文件上传
如果你的需求只是多文件上传,不需要ModelViewSet的其他功能,可以直接用APIView简化实现:
修改views.py
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import File from .serializers import FilesSerializer, FileSerializer class MultipleFileUploadView(APIView): parser_classes = (FormParser, MultiPartParser) def post(self, request, format=None): serializer = FilesSerializer(data=request.data) if serializer.is_valid(): file_objs = serializer.save() return Response(FileSerializer(file_objs, many=True).data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
关键要点总结
- 明确区分单个实例序列化器和多文件上传序列化器的职责,不要混用
- 当处理批量创建返回列表时,必须用
many=True参数告诉序列化器要处理多个实例 - ModelViewSet默认的
create方法仅支持单个实例操作,批量场景需要自定义action或者改用APIView
内容的提问来源于stack exchange,提问作者Hugo
相关产品推荐
相关产品推荐

