Django Rest Framework中Patch请求测试失败问题排查
Django Rest Framework Patch测试请求数据为空问题解决
问题描述
在Django Rest Framework中编写了Post与Patch两个测试用例,Post请求测试正常,但Patch请求测试失败(生产环境中两者均可正常运行)。视图均使用默认的UpdateMixin和CreateMixin,序列化器相同,但Patch请求的request.data为空,导致断言返回的pictures长度为1失败(实际返回0)。相关测试代码如下:
with open(os.path.join(self.path, "..", "..", "plugin/test_files/icons.png"), 'rb') as file_obj: document = SimpleUploadedFile( file_obj.name, file_obj.read(), content_type='image/png') re = self.patch(f"/api/units/{unit_id}/", {"files": [document]}, content_type=MULTIPART_CONTENT) self.assertIn('pictures', re) self.assertEqual(len(re["pictures"]), 1) # Fails with 0 != 1 with open(os.path.join(self.path, "..", "..", "plugin/test_files/icons.png"), 'rb') as file_obj: document = SimpleUploadedFile( file_obj.name, file_obj.read(), content_type='image/png') re = self.post("/api/units/", {"company_id": 1, "name": "test", "address_id": 1, "files": [document]}, content_type=MULTIPART_CONTENT) self.assertIn('pictures', re) self.assertEqual(len(re["pictures"]), 1)
请问如何让Patch请求的数据正常到达后端?
问题原因
DRF测试客户端处理PATCH请求的多部分表单数据时,默认逻辑和POST请求不同,不会自动解析文件上传数据,导致request.data为空。
解决方法
方法1:使用format='multipart'参数
去掉手动指定的content_type=MULTIPART_CONTENT,改用测试客户端的format参数,让客户端自动处理多部分表单编码:
re = self.patch( f"/api/units/{unit_id}/", {"files": [document]}, format='multipart' )
方法2:手动构造规范的多部分请求体
如果必须手动指定content_type,可以用MultipartEncoder构造符合格式的请求数据:
from requests_toolbelt.multipart.encoder import MultipartEncoder multipart_data = MultipartEncoder( fields={ 'files': (document.name, document, 'image/png') } ) re = self.patch( f"/api/units/{unit_id}/", data=multipart_data, content_type=multipart_data.content_type )
方法3:检查视图解析器配置
确认视图类的parser_classes中包含MultiPartParser(默认已包含,若有自定义配置需检查):
from rest_framework.parsers import MultiPartParser, FormParser class UnitViewSet(viewsets.ModelViewSet): parser_classes = (MultiPartParser, FormParser) # 其他视图配置...
内容的提问来源于stack exchange,提问作者creyD
相关产品推荐
相关产品推荐

