【问题标题】:Django Rest Framework APIClient does not parse query parametersDjango Rest Framework APIClient 不解析查询参数
【发布时间】:2016-11-17 18:04:05
【问题描述】:

我正在使用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')

我得到的参数解析不正确:

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

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

【问题讨论】:

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


    【解决方案1】:

    对我来说,问题在于 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)
    

    【讨论】:

    • 我相信你可能误解了这个问题;它询问query_params 不请求数据
    【解决方案2】:

    您的查询参数格式不正确。

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

    【讨论】:

    • 这个想法是获取查询参数,并按照我需要的方式解析它们。例如,可能有像/api/v2/resource/1/users/?fields=first_name;last_name 这样的参数,它将被解析为集合{'first_name', 'last_name'}。还有一个选项/api/v2/resource/1/users/?fields=1-4,在后台将被解析为集合{'first_name', 'last_name', 'phone', 'skype'}。而且,另一个问题仍然存在 client.get('/api/v2/resource/1/users/?fields=first_name;last_name') 导致空 query_params
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 2018-10-16
      相关资源
      最近更新 更多