简体   繁体   中英

How can I make an HTTP request with no Content-Type header using django.test.Client?

I have a Django application which must have the following behavior: if a request has no Content-Type header, it returns an error response.

In order to test this behavior, I need to make an HTTP request without a Content-Type header.

I am using the Client class in the django.test module . This has many methods, including this one:

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

Makes a POST request on the provided path and returns a Response object, which is documented below.

[...]

If you provide content_type (eg text/xml for an XML payload), the contents of data will be sent as-is in the POST request, using content_type in the HTTP Content-Type header.

If you don't provide a value for content_type , the values in data will be transmitted with a content type of multipart/form-data . In this case, the key-value pairs in data will be encoded as a multipart message and used to create the POST data payload.

The documentation says that a Content-Type header is always set on the request, irrespective of whether I pass a content_type argument.

So what other ways do I have to construct a request, such that it does not have a Content-Type header?

You can build a customised request instance through the class RequestFactory .

Once generated, you can modify the request instance before passing it to the view.


Using the example in the RequestFactory documentation page as a starting point, you can do:

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)

The request.META is just a standard Python dictionary (as explained here ), so you can use

del request.META['CONTENT_TYPE']

instead of pop() to remove it, but only if you are deadly sure that the key will be in the dictionary.

I know this is several years old, but I had the same question and found the real answer, ie how to do this with the test client:

client.get(url, content_type=None)

At least on Django 2.0, that makes a request with no content type header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM