Django Rest Framework (DRF)的APIClient是用于测试API的工具,它模拟了HTTP客户端的行为。当需要测试文件上传功能时,特别是多文件上传时,APIClient提供了便捷的方法来构造测试请求。
首先确保你的模型视图集(ModelViewSet)已经配置好处理多文件上传的功能。通常需要使用MultiPartParser
来解析multipart/form-data请求。
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.MultiPartParser', # 必须包含这个
],
}
假设我们有一个简单的模型和序列化器:
# models.py
from django.db import models
class UploadedFile(models.Model):
file = models.FileField(upload_to='uploads/')
uploaded_at = models.DateTimeField(auto_now_add=True)
# serializers.py
from rest_framework import serializers
from .models import UploadedFile
class FileUploadSerializer(serializers.ModelSerializer):
class Meta:
model = UploadedFile
fields = '__all__'
# views.py
from rest_framework import viewsets
from .models import UploadedFile
from .serializers import FileUploadSerializer
class FileUploadViewSet(viewsets.ModelViewSet):
queryset = UploadedFile.objects.all()
serializer_class = FileUploadSerializer
使用APIClient测试多文件上传的示例:
from django.test import TestCase
from rest_framework.test import APIClient
from django.core.files.uploadedfile import SimpleUploadedFile
import os
class MultiFileUploadTest(TestCase):
def setUp(self):
self.client = APIClient()
def test_multiple_file_upload(self):
# 创建多个模拟文件
file1 = SimpleUploadedFile("file1.txt", b"file_content_1", content_type="text/plain")
file2 = SimpleUploadedFile("file2.txt", b"file_content_2", content_type="text/plain")
file3 = SimpleUploadedFile("file3.jpg", b"file_content_3", content_type="image/jpeg")
# 方法1:使用data参数传递文件列表
response = self.client.post('/api/upload/', data={'file': [file1, file2, file3]}, format='multipart')
self.assertEqual(response.status_code, 201)
# 方法2:逐个上传文件
for file in [file1, file2, file3]:
response = self.client.post('/api/upload/', data={'file': file}, format='multipart')
self.assertEqual(response.status_code, 201)
如果你的视图集需要同时接收多个文件,可以修改视图集:
# views.py
from rest_framework import status
from rest_framework.response import Response
class FileUploadViewSet(viewsets.ModelViewSet):
# ... 其他代码同上
def create(self, request, *args, **kwargs):
# 处理单个文件上传
if 'file' in request.data and not isinstance(request.data['file'], list):
return super().create(request, *args, **kwargs)
# 处理多文件上传
if 'file' in request.data and isinstance(request.data['file'], list):
files = request.data.getlist('file')
created_files = []
for file in files:
file_data = {'file': file}
serializer = self.get_serializer(data=file_data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
created_files.append(serializer.data)
headers = self.get_success_headers(serializer.data)
return Response(created_files, status=status.HTTP_201_CREATED, headers=headers)
return Response({'error': 'No files provided'}, status=status.HTTP_400_BAD_REQUEST)
原因:
format='multipart'
MultiPartParser
解决方案:
# 确保测试代码中指定了format参数
response = self.client.post('/api/upload/', data={'file': file}, format='multipart')
原因:
解决方案: 参考上面的视图集修改示例,添加对文件列表的处理逻辑。
原因:
SimpleUploadedFile
创建测试文件时内容不正确解决方案:
# 确保正确创建测试文件
file = SimpleUploadedFile(
name="test_file.txt",
content=b"test content",
content_type="text/plain"
)
SimpleUploadedFile
创建内存中的文件对象没有搜到相关的文章