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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:07:18