Index: docs/topics/http/decorators.txt
===================================================================
--- docs/topics/http/decorators.txt	(revision 15894)
+++ docs/topics/http/decorators.txt	(working copy)
@@ -10,8 +10,8 @@
 Allowed HTTP methods
 ====================
 
-The following decorators in :mod:`django.views.decorators.http` can be used to
-restrict access to views based on the request method.
+The decorators in :mod:`django.views.decorators.http` can be used to restrict
+access to views based on the request method.
 
 .. function:: require_http_methods(request_method_list)
 
@@ -28,6 +28,25 @@
 
 Note that request methods should be in uppercase.
 
+Furthermore, the following decorators provide shortcuts for the most common
+use cases.
+
+.. function:: require_safe()
+
+This decorator requires that a view only accept the GET and HEAD methods. These
+methods are called "safe" because they should not have any side effects besides
+retrieving the requested resource.
+
+.. note::
+    Django will automatically strip the content of responses to HEAD requests
+    while leaving the headers unchanged, so you can handle HEAD requests
+    exactly like GET requests in your views. Since some software, such as link
+    checkers, relies on HEAD requests, you should generally use
+    ``require_safe`` instead of ``require_GET``.
+
+.. versionadded:: 1.4
+    The ``require_safe`` decorator was added.
+
 .. function:: require_GET()
 
 Decorator to require that a view only accept the GET method.
Index: django/views/decorators/http.py
===================================================================
--- django/views/decorators/http.py	(revision 15894)
+++ django/views/decorators/http.py	(working copy)
@@ -52,6 +52,9 @@
 require_POST = require_http_methods(["POST"])
 require_POST.__doc__ = "Decorator to require that a view only accept the POST method."
 
+require_safe = require_http_methods(["GET", "HEAD"])
+require_safe.__doc__ = "Decorator to require that a view only accept safe methods: GET and HEAD."
+
 def condition(etag_func=None, last_modified_func=None):
     """
     Decorator to support conditional retrieval (or change) for a view
Index: tests/regressiontests/decorators/tests.py
===================================================================
--- tests/regressiontests/decorators/tests.py	(revision 15894)
+++ tests/regressiontests/decorators/tests.py	(working copy)
@@ -6,11 +6,11 @@
 
 from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
 from django.contrib.admin.views.decorators import staff_member_required
-from django.http import HttpResponse, HttpRequest
+from django.http import HttpResponse, HttpRequest, HttpResponseNotAllowed
 from django.utils.decorators import method_decorator
 from django.utils.functional import allow_lazy, lazy, memoize
 from django.utils.unittest import TestCase
-from django.views.decorators.http import require_http_methods, require_GET, require_POST
+from django.views.decorators.http import require_http_methods, require_GET, require_POST, require_safe
 from django.views.decorators.vary import vary_on_headers, vary_on_cookie
 from django.views.decorators.cache import cache_page, never_cache, cache_control
 
@@ -24,6 +24,7 @@
 fully_decorated = require_http_methods(["GET"])(fully_decorated)
 fully_decorated = require_GET(fully_decorated)
 fully_decorated = require_POST(fully_decorated)
+fully_decorated = require_safe(fully_decorated)
 
 # django.views.decorators.vary
 fully_decorated = vary_on_headers('Accept-language')(fully_decorated)
@@ -115,7 +116,28 @@
         my_view_cached4 = cache_page()(my_view)
         self.assertEqual(my_view_cached4(HttpRequest()), "response")
 
+    def test_require_safe_accepts_only_safe_methods(self):
+        """
+        Test for the require_safe decorator
+        
+        A view returns either a response or an exception.
+        """
+        def my_view(request):
+            return HttpResponse("OK")
+        my_safe_view = require_safe(my_view)
+        request = HttpRequest()
+        request.method = 'GET'
+        self.assertTrue(isinstance(my_safe_view(request), HttpResponse))
+        request.method = 'HEAD'
+        self.assertTrue(isinstance(my_safe_view(request), HttpResponse))
+        request.method = 'POST'
+        self.assertTrue(isinstance(my_safe_view(request), HttpResponseNotAllowed))
+        request.method = 'PUT'
+        self.assertTrue(isinstance(my_safe_view(request), HttpResponseNotAllowed))
+        request.method = 'DELETE'
+        self.assertTrue(isinstance(my_safe_view(request), HttpResponseNotAllowed))
 
+
 # For testing method_decorator, a decorator that assumes a single argument.
 # We will get type arguments if there is a mismatch in the number of arguments.
 def simple_dec(func):
