在 Django 测试中设置 headers(API 版本控制)

Setting headers in Django tests (API versioning)

我将 AcceptHeaderVersioning 与 Django rest 框架一起使用,如下所述:

https://www.django-rest-framework.org/api-guide/versioning/#versioning-with-rest-framework

我想测试 API returns 如果未指定版本但为正确版本则为默认版本。但是,似乎不可能将版本参数传递给测试。这是一个例子:

def testCheckVersion(self):
    versions = [u'v0.1', u'v0.2']
    self.key = APIKey(name='Example Key')
    self.key.save()
    for version in versions:
        response = self.client.get('/api/data/',
                                   VERSION="{0}".format(version),
                                   **{'Api-Key': self.key.key})
        self.assertEqual(response.status_code, 200)
        content = json.loads(response.content)
        self.assertEqual(content['api_version'], version)

这总是给出默认的 api 版本(在本例中为 v0.2)。我已经尝试了 re-working response = 行的各种方法,但没有成功。这也许可以通过使用 QueryParameterVersioning 来解决,但我宁愿不这样做,所以如果您有任何建议,请告诉我。

https://www.django-rest-framework.org/api-guide/versioning/#acceptheaderversioning

文档说您需要在 Accept header 中包含版本,使用他们的示例:

Here's an example HTTP request using the accept header versioning style.

GET /bookings/ HTTP/1.1
Host: example.com
Accept: application/json; version=1.0

In the example request above request.version attribute would return the string '1.0'.

根据 Django 文档 https://docs.djangoproject.com/en/1.11/ref/request-response/#django.http.HttpRequest.META:

,您还错误地设置了 self.client.get() 调用中的 header

With the exception of CONTENT_LENGTH and CONTENT_TYPE, as given above, any HTTP headers in the request are converted to META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name. So, for example, a header called X-Bender would be mapped to the META key HTTP_X_BENDER.

您的结果测试可能看起来更像这样:

def testCheckVersion(self):
    versions = [u'v0.1', u'v0.2']
    self.key = APIKey(name='Example Key')
    self.key.save()
    for version in versions:

        ### This call has changed
        response = self.client.get(
            '/api/data/',
            HTTP_ACCEPT=f"application/json; version={version}"
        )

        self.assertEqual(response.status_code, 200)
        content = json.loads(response.content)
        self.assertEqual(content['api_version'], version)