diff --git a/django/test/client.py b/django/test/client.py index 6bdc1cf3d37..bb0f25e108c 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -319,6 +319,11 @@ class RequestFactory(object): "Construct a PUT request." return self.generic('PUT', path, data, content_type, **extra) + def patch(self, path, data='', content_type='application/octet-stream', + **extra): + "Construct a PATCH request." + return self.generic('PATCH', path, data, content_type, **extra) + def delete(self, path, data='', content_type='application/octet-stream', **extra): "Construct a DELETE request." @@ -496,6 +501,17 @@ class Client(RequestFactory): response = self._handle_redirects(response, **extra) return response + def patch(self, path, data='', content_type='application/octet-stream', + follow=False, **extra): + """ + Send a resource to the server using PATCH. + """ + response = super(Client, self).patch( + path, data=data, content_type=content_type, **extra) + if follow: + response = self._handle_redirects(response, **extra) + return response + def delete(self, path, data='', content_type='application/octet-stream', follow=False, **extra): """ diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt index 5739061dd11..3b2babd3027 100644 --- a/docs/topics/testing/overview.txt +++ b/docs/topics/testing/overview.txt @@ -633,6 +633,14 @@ Use the ``django.test.client.Client`` class to make requests. The ``follow`` and ``extra`` arguments act the same as for :meth:`Client.get`. + .. method:: Client.patch(path, data='', content_type='application/octet-stream', follow=False, **extra) + + Makes a PATCH request on the provided ``path`` and returns a + ``Response`` object. Useful for testing RESTful interfaces. + + The ``follow`` and ``extra`` arguments act the same as for + :meth:`Client.get`. + .. method:: Client.delete(path, data='', content_type='application/octet-stream', follow=False, **extra) Makes an DELETE request on the provided ``path`` and returns a diff --git a/tests/regressiontests/test_client_regress/tests.py b/tests/regressiontests/test_client_regress/tests.py index 5ba5d3c4b3f..c52715239b4 100644 --- a/tests/regressiontests/test_client_regress/tests.py +++ b/tests/regressiontests/test_client_regress/tests.py @@ -783,6 +783,13 @@ class RequestMethodTests(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'request method: DELETE') + def test_patch(self): + "Request a view via request method PATCH" + response = self.client.patch('/test_client_regress/request_methods/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.content, b'request method: PATCH') + + class RequestMethodStringDataTests(TestCase): def test_post(self): "Request a view with string data via request method POST" @@ -800,6 +807,14 @@ class RequestMethodStringDataTests(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'request method: PUT') + def test_patch(self): + "Request a view with string data via request method PATCH" + # Regression test for #17797 + data = u'{"test": "json"}' + response = self.client.patch('/test_client_regress/request_methods/', data=data, content_type='application/json') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.content, b'request method: PATCH') + class QueryStringTests(TestCase): def test_get_like_requests(self): # See: https://code.djangoproject.com/ticket/10571.