APIClient的PUT调用中的查询参数

时间:2018-10-02 12:56:39

标签: django django-testing apiclient

我有一个API端点,我想对它进行PUT调用,它需要正文和查询参数。我使用Django的测试客户端在测试案例(docs)中调用端点。

我在文档中读到,对于GET调用,使用参数data引入了查询参数。我还了解到,对于PUT调用,参数data代表主体。我错过了有关如何在PUT调用中添加查询参数的文档。

尤其是,此测试用例失败:

data = ['image_1', 'image_2']
url = reverse('images')
response = self.client.put(url, 
                           data=data, 
                           content_type='application/json', 
                           params={'width': 100, 'height': 200})

此测试用例通过:

data = ['image_1', 'image_2']
url = reverse('images') + '?width=100&height=200'
response = self.client.put(url, 
                           data=data, 
                           content_type='application/json')

换句话说:真的需要手动构建网址吗?

2 个答案:

答案 0 :(得分:1)

假设您使用的是rest_framework的APITestClient,我发现了这一点:

def get(self, path, data=None, secure=False, **extra):
    """Construct a GET request."""
    data = {} if data is None else data
    r = {
        'QUERY_STRING': urlencode(data, doseq=True),
    }
    r.update(extra)
    return self.generic('GET', path, secure=secure, **r)

看跌期权是:

def put(self, path, data='', content_type='application/octet-stream',
        secure=False, **extra):
    """Construct a PUT request."""
    return self.generic('PUT', path, data, content_type,
                        secure=secure, **extra)

和有趣的部分(摘录自self.generic代码):

    # If QUERY_STRING is absent or empty, we want to extract it from the URL.
    if not r.get('QUERY_STRING'):
        # WSGI requires latin-1 encoded strings. See get_path_info().
        query_string = force_bytes(parsed[4]).decode('iso-8859-1')
        r['QUERY_STRING'] = query_string
    return self.request(**r)

所以您可能尝试使用QUERY_STRING创建该字典并将其传递给put的kwargs,但我不确定这是多么值得努力。

答案 1 :(得分:0)

我只是指定@henriquesalvaro回答的更多细节。

您可以使用PUTPOST这样的方法传递查询参数。

# tests.py
def test_xxxxx(self):
    url = 'xxxxx'
    res = self.client.put(url,**{'QUERY_STRING': 'a=10&b=20'})

# views.py
class TestViewSet(.....):

    def ...(self, request, *args, **kwargs):
        print(request.query_params.get('a'))
        print(request.query_params.get('b'))