Django Rest Framework APIClient不解析查询参数

时间:2016-07-14 17:34:33

标签: django django-rest-framework django-testing

我正在使用djangorestframework==3.3.3Django==1.9.4

我有一个测试,我想检查正确处理的查询参数。

class TestResourceView(APITestCase):

    def test_view_process_query_params_correctly(self):
        client = APIClient()
        client.login(username='<username>', password='password')
        response = client.get('/api/v2/resource/1/users/?fields=first_name;last_name')
        self.assertEqual(response.status_code, 200)
        # .... rest of the test .... 

在我的视图中,我只是将print语句用于查看是否正确解析了查询参数,但我得到了空查询字典:

class Resource(APIView):
    def get(self, request):
        query_params = request.query_params
        print('Printing query params')
        print(query_params)
        # .... rest of the code ....

    def post(self, request):
        query_params = request.query_params
        print('Printing query params')
        print(query_params)
        # .... rest of the code ....

运行测试时终端结果:

Printing query params
<QueryDict: {}>

同时,如果我像这样测试post请求:

response = client.post('/api/v2/resource/1/users/?fields=first_name;last_name')

我得到params错误解析:

Printing query params
<QueryDict: {'last_name': [''], 'fields': ['first_name']}>

使用APIClient的正确方法是什么?或者这仍然是一个错误?因为已经有类似的issue

3 个答案:

答案 0 :(得分:0)

查询参数的格式不正确。

如果您希望结果为{'fields': ['last_name', 'first_name']},那么您的POST网址应为.../users/?fields=first_name&fields=last_name'。您可能希望使用getlist()访问参数。

答案 1 :(得分:0)

1)关于<QueryDict: {}>中的空client.get('/api/v2/resource/1/users/?fields=first_name;last_name') - 我的代码中出现了错误。我有两个同名的测试,其中一个确实有空<QueryDict: {}>。因此,在运行测试时,django使用<QueryDict: {}>

运行测试

2)关于client.post('/api/v2/resource/1/users/?fields=first_name;last_name')中查询参数的错误解析,我找到了以下discussion。所以,django基本上遵循HTTP标准,据说;分号是保留字符,如果使用,则是正确的理解方式,与&相同。这里有更多details

答案 2 :(得分:0)

对我来说,问题在于DRF希望data中的参数而不是像Django测试客户端那样的args中的参数。

此答案对我有帮助: https://stackoverflow.com/a/45183972/9512437

class AccountTests(APITestCase):

    def setUp(self):
        self.user = CustomUser.objects.create_user(email="user1@test.com", password="password1", is_staff=True)
        self.client = APIClient()

    def test_add_name(self):
        self.client.force_authenticate(self.user)

        url = reverse('customuser-detail', args=(self.user.id,))
        data = {'first_name': 'test', 'last_name': 'user'}
        response = self.client.put(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)