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

Django Rest Framework测试用例中GET请求无法识别查询参数

Django Rest Framework测试用例中GET请求查询参数未识别问题

问题描述

我有一个基于ListAPIView实现的接口,用于返回模型实例集合,需要通过project查询参数过滤指定项目的数据。Postman发送带该参数的GET请求时正常工作,但在测试用例中执行相同请求时,project参数未被识别,返回400错误,提示project字段为必填项。

测试用例简化代码

class ShiftListTests(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user(username='testuser', password='testpassword')
        self.client.force_authenticate(user=self.user)

        self.project = Project.objects.create(owner=self.user, task='Test Task',
                                              technical_requirement='Test Requirement', start='2023-05-01',
                                              hourly_rate=10.0)

        self.shift1 = Shift.objects.create(project=self.project,
                                           start_time=timezone.make_aware(timezone.datetime(2023, 5, 1, 9, 0, 0)),
                                           end_time=timezone.make_aware(timezone.datetime(2023, 5, 1, 17, 0, 0)))
        self.shift2 = Shift.objects.create(project=self.project,
                                           start_time=timezone.make_aware(timezone.datetime(2023, 5, 2, 9, 0, 0)),
                                           end_time=timezone.make_aware(timezone.datetime(2023, 5, 2, 17, 0, 0)))

    def test_get_shift_list(self):
        url = reverse('shift list')
        payload = {'project': self.project.id}
        response = self.client.get(url, data=payload, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        # Assertion and further processing...

错误信息

Failure
    Traceback (most recent call last):
        File "/Users/Tokio/Developer/ShiftBot/shift/tests/testShiftListEndPoint.py",
    line 44, in test_get_shift_list
    self.assertEqual(response.status_code, status.HTTP_200_OK)
    AssertionError: 400 != 200

{'project': ErrorDetail(string='This field is required', code='invalid')}

原因分析

问题出在测试用例中self.client.get()方法的参数使用上:当指定format='json'时,DRF测试客户端会将data中的内容放到请求体中发送,但GET请求的查询参数应该放在URL的查询字符串里,而你的视图是从URL查询参数中读取project值,因此无法识别请求体中的参数,导致校验失败。

Postman中发送请求时,是直接将project参数拼在URL的查询字符串中,符合接口的参数读取逻辑,所以能正常工作。

解决建议

有两种简单的修正方式:

  1. 移除format='json'参数
    DRF测试客户端默认会将GET请求的data参数转为URL查询参数,修改后的请求代码如下:

    response = self.client.get(url, data=payload)
    
  2. 手动构造带查询参数的URL
    可以用urlencode将参数拼到URL后,或者直接拼接字符串:

    from urllib.parse import urlencode
    
    url = f"{reverse('shift list')}?{urlencode(payload)}"
    response = self.client.get(url)
    

修改后,project参数会被正确放到URL查询字符串中,视图就能正常识别并过滤数据,测试用例即可通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:08:12