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

Django REST API文本文件上传测试报错求助

解决Django REST API文件上传的"提交数据不是文件"问题

嘿,我帮你排查下这个文件上传的问题!你遇到的错误提示说明请求格式不符合要求,Django REST Framework没法正确识别你传递的文件数据。下面分场景给你具体解决方案:

一、用requests库测试时的正确姿势

如果是用requests调用API,别直接传文件路径或裸临时文件对象,要严格按照multipart/form-data的格式构造请求:

import requests
from tempfile import NamedTemporaryFile

# 创建带正确扩展名的临时文件(服务器靠扩展名识别类型)
with NamedTemporaryFile(suffix='.txt', delete=False) as temp_cover:
    temp_cover.write(b"这是测试求职信内容")
    cover_path = temp_cover.name

# 构造files参数:每个字段是(文件名, 二进制文件对象, 内容类型)的元组
upload_url = "http://你的API地址/upload/"
files = {
    'cover_letter': ('my_cover.txt', open(cover_path, 'rb'), 'text/plain'),
    'manuscript': ('my_paper.pdf', open('/本地路径/你的论文.pdf', 'rb'), 'application/pdf')
}

# 发送请求,requests会自动设置正确的Content-Type为multipart/form-data
response = requests.post(upload_url, files=files)
print(response.json())

关键注意点:

  • 必须用rb模式打开文件(二进制读),文本模式会破坏文件结构
  • 文件名要带正确扩展名(比如.txt、.pdf),不然服务器的类型验证会直接失败
  • 无需手动设置请求头,requests会自动处理multipart/form-data格式

二、Django测试用例里的正确写法

如果是在Django的TestCase中测试,要用SimpleUploadedFile包装文件数据,并且指定format='multipart':

from django.test import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from rest_framework import status

class FileUploadAPITest(TestCase):
    def test_valid_file_upload(self):
        # 创建模拟上传文件,带正确扩展名和内容类型
        cover_file = SimpleUploadedFile(
            "cover_letter.txt",
            b"测试求职信内容",
            content_type="text/plain"
        )
        manuscript_file = SimpleUploadedFile(
            "research_paper.pdf",
            b"%PDF-1.4\n%模拟PDF内容...",
            content_type="application/pdf"
        )

        # 发送POST请求,必须指定format为multipart
        response = self.client.post(
            "/api/upload/",
            data={'cover_letter': cover_file, 'manuscript': manuscript_file},
            format='multipart'
        )

        # 验证请求成功
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

三、服务器端的验证要配套

确保你的序列化器里的文件字段配置了正确的类型验证,比如用FileExtensionValidator:

from rest_framework import serializers
from rest_framework.validators import FileExtensionValidator

class UploadSerializer(serializers.Serializer):
    cover_letter = serializers.FileField(
        validators=[FileExtensionValidator(allowed_extensions=['txt', 'doc', 'pdf'])],
        max_size=1024*100  # 可选:限制文件大小为100KB
    )
    manuscript = serializers.FileField(
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'doc', 'docx'])],
        max_size=1024*500
    )

常见坑总结

  • 不要用普通字典传文件数据,必须用files参数(requests)或SimpleUploadedFile(测试用例)包装
  • 文件名必须带正确扩展名,否则服务器无法识别文件类型
  • 打开文件必须用二进制模式rb,文本模式会导致文件数据损坏
  • 测试用例里必须加format='multipart',否则Django测试客户端会默认用application/json格式发送,导致文件无法被识别

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:35:48