Index: django/test/client.py
===================================================================
--- django/test/client.py	(revision 9050)
+++ django/test/client.py	(working copy)
@@ -284,6 +284,69 @@
 
         return self.request(**r)
 
+    def head(self, path, data={}, **extra):
+        """
+        Request a response from the server using HEAD.
+        """
+        r = {
+            'CONTENT_LENGTH':  None, 
+            'CONTENT_TYPE':    'text/html; charset=utf-8',
+            'PATH_INFO':       urllib.unquote(path),
+            'QUERY_STRING':    urlencode(data, doseq=True),
+            'REQUEST_METHOD': 'HEAD',
+        }
+        r.update(extra)
+
+        return self.request(**r)
+        
+    def options(self, path, data={}, **extra):
+        """
+        Request a response from the server using OPTIONS.
+        """
+        r = {
+            'CONTENT_LENGTH':  None,
+            'CONTENT_TYPE':    None,
+            'PATH_INFO':       urllib.unquote(path),
+            'QUERY_STRING':    urlencode(data, doseq=True),
+            'REQUEST_METHOD': 'OPTIONS',
+        }
+        r.update(extra)
+
+        return self.request(**r)
+
+    def put(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
+        """
+        Send a resource to the server using PUT.
+        """
+        if content_type is MULTIPART_CONTENT:
+            post_data = encode_multipart(BOUNDARY, data)
+        else:
+            post_data = data
+        r = { 
+            'CONTENT_LENGTH': len(post_data),
+            'CONTENT_TYPE':   content_type,
+            'PATH_INFO':      urllib.unquote(path),
+            'REQUEST_METHOD': 'PUT',
+            'wsgi.input':     FakePayload(post_data),
+        }
+        r.update(extra)
+
+        return self.request(**r)
+
+    def delete(self, path, data={}, **extra):
+        """
+        Send a DELETE request to the server.
+        """
+        r = {
+            'CONTENT_LENGTH':  None,
+            'CONTENT_TYPE':    None,
+            'PATH_INFO':       urllib.unquote(path),
+            'REQUEST_METHOD': 'DELETE',
+            } 
+        r.update(extra)
+
+        return self.request(**r)
+
     def login(self, **credentials):
         """
         Sets the Client to appear as if it has successfully logged into a site.
Index: tests/regressiontests/test_client_regress/views.py
===================================================================
--- tests/regressiontests/test_client_regress/views.py	(revision 9050)
+++ tests/regressiontests/test_client_regress/views.py	(working copy)
@@ -43,3 +43,7 @@
 def check_session_view(request):
     "A view that reads a session variable"
     return HttpResponse(request.session.get('session_var', 'NO'))
+
+def request_methods_view(request):
+    "A view that responds with the request method"
+    return HttpResponse('request method: %s' % request.method)
\ No newline at end of file
Index: tests/regressiontests/test_client_regress/models.py
===================================================================
--- tests/regressiontests/test_client_regress/models.py	(revision 9050)
+++ tests/regressiontests/test_client_regress/models.py	(working copy)
@@ -382,4 +382,41 @@
         response = self.client.get('/test_client_regress/check_session/')
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.content, 'YES')
-        
\ No newline at end of file
+
+class RequestMethodTests(TestCase):
+    def test_get(self):
+        "Request a view via request method GET"
+        response = self.client.get('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'request method: GET')
+
+    def test_post(self):
+        "Request a view via request method POST"
+        response = self.client.post('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'request method: POST')
+
+    def test_head(self):
+        "Request a view via request method HEAD"
+        response = self.client.head('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertNotEqual(response.content, 'request method: HEAD')
+        self.assertEqual(response.content, '')
+
+    def test_options(self):
+        "Request a view via request method OPTIONS"
+        response = self.client.options('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'request method: OPTIONS')
+
+    def test_put(self):
+        "Request a view via request method PUT"
+        response = self.client.put('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'request method: PUT')
+
+    def test_delete(self):
+        "Request a view via request method DELETE"
+        response = self.client.delete('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'request method: DELETE')
\ No newline at end of file
Index: tests/regressiontests/test_client_regress/urls.py
===================================================================
--- tests/regressiontests/test_client_regress/urls.py	(revision 9050)
+++ tests/regressiontests/test_client_regress/urls.py	(working copy)
@@ -9,4 +9,5 @@
     (r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
     (r'^set_session/$', views.set_session_view),
     (r'^check_session/$', views.check_session_view),
+    (r'^request_methods/$', views.request_methods_view),
 )
Index: docs/topics/testing.txt
===================================================================
--- docs/topics/testing.txt	(revision 9050)
+++ docs/topics/testing.txt	(working copy)
@@ -544,6 +544,28 @@
         Note that you should manually close the file after it has been provided
         to ``post()``.
 
+    .. method:: Client.head(path, data={})
+
+        Makes a HEAD request on the provided ``path`` and returns a ``Response``
+        object. Useful for testing RESTful interfaces. Acts just like
+        :meth:`Client.get` except it does not return a message body.
+
+    .. method:: Client.options(path, data={})
+
+        Makes an OPTIONS request on the provided ``path`` and returns a
+        ``Response`` object. Useful for testing RESTful interfaces.
+
+    .. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT)
+
+        Makes an PUT request on the provided ``path`` and returns a
+        ``Response`` object. Useful for testing RESTful interfaces. Acts just
+        like :meth:`Client.put` except with the PUT request method.
+
+    .. method:: Client.delete(path)
+
+        Makes an DELETE request on the provided ``path`` and returns a
+        ``Response`` object. Useful for testing RESTful interfaces.
+
     .. method:: Client.login(**credentials)
 
         .. versionadded:: 1.0
