如何使用django.test.Client创建没有Content-Type标头的HTTP请求?

时间:2015-02-23 16:54:47

标签: python django unit-testing http http-headers

我有一个Django应用程序必须具有以下行为:如果请求没有Content-Type标头,则返回错误响应。

为了测试此行为,我需要在没有Content-Type标头的情况下发出HTTP请求。

我正在使用the Client class in the django.test module。这有很多方法,包括这个方法:

post(path, data=None, content_type=MULTIPART_CONTENT, follow=False, secure=False, **extra)
     

在提供的路径上发出POST请求并返回Response对象,如下所示。

     

[...]

     

如果您为XML有效负载提供content_type(例如text/xml),则使用HTTP content_type标头中的Content-Type将数据内容按原样发送到POST请求中

     

如果您没有为content_type提供值,则数据中的值将以内容类型multipart/form-data传输。在这种情况下,数据中的键值对将被编码为多部分消息,并用于创建POST数据有效负载。

文档说,无论我是否传递Content-Type参数,始终会在请求中设置content_type标头。

那么我还有什么方法可以构建一个请求,这样它就没有Content-Type标题?

2 个答案:

答案 0 :(得分:2)

您可以通过课程RequestFactory构建自定义请求实例。

生成后,您可以在将请求实例传递给视图之前对其进行修改。


使用RequestFactory文档页面中的示例作为起点,您可以执行以下操作:

from django.test import TestCase, RequestFactory
from .views import my_view

class SimpleTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.factory = RequestFactory()

    def test_details(self):
        # Create an instance of a POST request.
        request = self.factory.post('/your/url', data={'your':'data'})

        # NOW you can customise your request instance!
        # (i.e. remove the Content-Type header)
        request.META.pop('CONTENT_TYPE', None)

        # Actually use the request to test my_view() 
        # as if it were deployed at /customer/details
        response = my_view(request)
        self.assertEqual(response.status_code, 400)

request.META只是一个标准的Python字典(如here所述),所以你可以使用

del request.META['CONTENT_TYPE']

而不是pop()将其删除,但前提是您确定密钥将在字典中。

答案 1 :(得分:0)

我知道这已经有好几年了,但是我有一个相同的问题,并且找到了真正的答案,即如何与测试客户端一起做到这一点:

client.get(url, content_type=None)

至少在Django 2.0上,该请求没有内容类型标头。