DRF对接React上传文件至AWS S3时出现400错误求助
排查DRF + Uppy文件上传400错误的解决方案
400 Bad Request通常意味着前端发送的请求数据不符合DRF接口的验证规则,结合你给出的代码,我整理了几个最可能的原因和对应的解决办法:
1. 表单字段名不匹配(最可能的原因)
你的Django模型里文件字段是datafile,但React代码中Uppy的XHRUpload设置的fieldName是filedata——拼写完全错误了! DRF的序列化器找不到对应字段,直接返回400错误。
解决办法:
修改Uppy的fieldName为和模型一致的datafile:
uppy.use(XHRUpload, { endpoint: 'http://localhost:8000/api/v1/files/', fieldName: 'datafile', // 修正字段名拼写 headers: { Authorization: `JWT ${token}` } });
2. 外键字段type的传递错误
Django模型里的type是Doctype的外键,需要传递该模型的主键ID,但前端代码存在两个问题:
- 字段名用了
filetype,和模型/序列化器的type不匹配; - 大概率传递的是文件类型名称字符串,而非Doctype的ID值。
解决办法:
- 修正前端meta字段名,把
filetype改成type; - 确保传递的是Doctype的ID(比如从下拉选择框获取对应ID,而不是显示的名称):
this.state.uppy.setMeta({ filename: this.state.form.filename, type: this.state.form.fileTypeId // 替换为实际的Doctype主键ID });
3. 序列化器字段验证问题(需确认)
你没提供DocumentsSerializer的代码,但要确保:
datafile、filename、type这些字段都在序列化器中正确定义,且filename为必填字段;- 外键字段
type使用默认的PrimaryKeyRelatedField,确保能接收ID值。
这里给一个标准的序列化器示例:
from rest_framework import serializers from .models import Documents class DocumentsSerializer(serializers.ModelSerializer): class Meta: model = Documents fields = ['id', 'author', 'upload', 'filename', 'datafile', 'created', 'type'] # author和created由后端自动填充,设置为只读 read_only_fields = ['author', 'created']
4. 额外检查:请求内容类型
Uppy的XHRUpload默认会使用multipart/form-data(文件上传的正确类型),但如果你的DRF视图未配置对应解析器,可以手动添加:
from rest_framework.parsers import MultiPartParser, FormParser class DocumentsListView(AwsUrlMixin, viewsets.ViewSetMixin, generics.ListCreateAPIView): queryset = Documents.objects.all() serializer_class = DocumentsSerializer permission_classes = (IsAuthenticated, LifeLinePermissions) pagination_class = None parsers = [MultiPartParser, FormParser] # 添加解析器配置 def perform_create(self, serializer): serializer.save(author=self.request.user)
测试建议
你可以先用Postman或curl模拟请求,确认DRF接口的参数要求,再和前端发送的请求对比:
curl -X POST http://localhost:8000/api/v1/files/ \ -H "Authorization: JWT YOUR_TOKEN" \ -F "datafile=@/path/to/your/test-file.jpg" \ -F "filename=test-document" \ -F "type=1" # 替换为系统中存在的Doctype主键ID
如果curl请求能成功,那问题肯定出在前端的参数传递上。
内容的提问来源于stack exchange,提问作者Jekson
相关产品推荐
相关产品推荐

