Django 测试客户端方法覆盖标头

问题描述 投票:0回答:3

我正在尝试在我的视图集上测试我的更新方法。视图集是取自 drf 的模型视图集。要更新我需要发送一个 put 请求。由于这并不总是支持,有两种方法可以告诉服务器我正在发出 put 请求,第一种不符合我的需求是使用一个名为

_method
的附加字段并将其设置为
put
。由于我需要发布 json 数据,因此我需要使用第二种方式,即使用
X-HTTP-Method-Override
标头。

为了在测试用例中发布我的数据,我使用以下代码:

header = {'X_HTTP_METHOD_OVERRIDE': 'PUT'}
response = client.post('/model/1/', content_type='application/json', data=post_data_clean, **header)

但不幸的是我得到的结果是

{'detail':'Method POST not allowed.'}
。我使用插件(Postman)测试了服务器的行为,其中我也指定了
X-HTTP-Method-Override
标头。没有例外。我现在需要知道如何正确地将标头传递到 django 测试客户端,否则测试在这里会变得非常烦人。

python django django-rest-framework put x-http-method-override
3个回答
98
投票

您需要将标题指定为

'HTTP_X_HTTP_METHOD_OVERRIDE'
而不是
'X_HTTP_METHOD_OVERRIDE'
,即在标题的开头添加
HTTP_

header = {'HTTP_X_HTTP_METHOD_OVERRIDE': 'PUT'}
response = client.post('/model/1/', content_type='application/json', data=post_data_clean, **header)

来自 Django 文档:

请求中的 HTTP 标头通过转换转换为

META

 键
  所有字符均为大写,用下划线替换所有连字符
  并
在名称中添加 HTTP_
 前缀
。因此,例如,一个标题 称为
X-Bender
 将映射到 
META
HTTP_X_BENDER


12
投票
此外,您可以将标头传递给客户端的构造函数:

from django.test import Client client = Client(HTTP_USER_AGENT="Mozilla/5.0 ...", HTTP_X_USER_ID="982734")

这样每个请求都将包含默认标头。

PS:此方法对 DRF TestApiClient 和 ApiRequestFactory 有效。


0
投票
Django 4.2 提供了

headers

 关键字参数。请参阅 
Django 4.2 发行说明

RequestFactory、AsyncRequestFactory、Client 和 AsyncClient 类现在支持 headers 参数,该参数接受标头名称和值的字典。这允许使用更自然的语法来声明标头。

# Before: self.client.get("/home/", HTTP_ACCEPT_LANGUAGE="fr") await self.async_client.get("/home/", ACCEPT_LANGUAGE="fr") # After: self.client.get("/home/", headers={"accept-language": "fr"}) await self.async_client.get("/home/", headers={"accept-language": "fr"})

    
© www.soinside.com 2019 - 2024. All rights reserved.