Author: jezdez
Date: 2011-04-28 06:04:16 -0700 (Thu, 28 Apr 2011)
New Revision: 16115
Modified:
django/trunk/django/views/decorators/http.py
django/trunk/docs/topics/http/decorators.txt
django/trunk/tests/regressiontests/decorators/tests.py
Log:
Fixed #15637 -- Added a require_safe decorator for views to accept GET or HEAD.
Thanks, aaugustin and Julien.
Modified: django/trunk/django/views/decorators/http.py
===================================================================
--- django/trunk/django/views/decorators/http.py 2011-04-28 01:47:21 UTC
(rev 16114)
+++ django/trunk/django/views/decorators/http.py 2011-04-28 13:04:16 UTC
(rev 16115)
@@ -48,6 +48,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
Modified: django/trunk/docs/topics/http/decorators.txt
===================================================================
--- django/trunk/docs/topics/http/decorators.txt 2011-04-28 01:47:21 UTC
(rev 16114)
+++ django/trunk/docs/topics/http/decorators.txt 2011-04-28 13:04:16 UTC
(rev 16115)
@@ -10,32 +10,48 @@
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)
-This decorator is used to ensure that a view only accepts particular request
-methods. Usage::
+ Decorator to require that a view only accept particular request
+ methods. Usage::
- from django.views.decorators.http import require_http_methods
+ from django.views.decorators.http import require_http_methods
- @require_http_methods(["GET", "POST"])
- def my_view(request):
- # I can assume now that only GET or POST requests make it this far
- # ...
- pass
+ @require_http_methods(["GET", "POST"])
+ def my_view(request):
+ # I can assume now that only GET or POST requests make it this far
+ # ...
+ pass
-Note that request methods should be in uppercase.
+ Note that request methods should be in uppercase.
.. function:: require_GET()
-Decorator to require that a view only accept the GET method.
+ Decorator to require that a view only accept the GET method.
.. function:: require_POST()
-Decorator to require that a view only accept the POST method.
+ Decorator to require that a view only accept the POST method.
+.. function:: require_safe()
+
+ .. versionadded:: 1.4
+
+ Decorator to require that a view only accept the GET and HEAD methods.
+ These methods are commonly considered "safe" because they should not have
+ the significance of taking an action other than retrieving the requested
+ resource.
+
+ .. note::
+ Django will automatically strip the content of responses to HEAD
+ requests while leaving the headers unchanged, so you may handle HEAD
+ requests exactly like GET requests in your views. Since some software,
+ such as link checkers, rely on HEAD requests, you might prefer
+ using ``require_safe`` instead of ``require_GET``.
+
Conditional view processing
===========================
@@ -48,9 +64,9 @@
.. function:: last_modified(last_modified_func)
-These decorators can be used to generate ``ETag`` and ``Last-Modified``
-headers; see
-:doc:`conditional view processing </topics/conditional-view-processing>`.
+ These decorators can be used to generate ``ETag`` and ``Last-Modified``
+ headers; see
+ :doc:`conditional view processing </topics/conditional-view-processing>`.
.. module:: django.views.decorators.gzip
@@ -62,9 +78,9 @@
.. function:: gzip_page()
-This decorator compresses content if the browser allows gzip compression.
-It sets the ``Vary`` header accordingly, so that caches will base their
-storage on the ``Accept-Encoding`` header.
+ This decorator compresses content if the browser allows gzip compression.
+ It sets the ``Vary`` header accordingly, so that caches will base their
+ storage on the ``Accept-Encoding`` header.
.. module:: django.views.decorators.vary
@@ -78,7 +94,7 @@
.. function:: vary_on_headers(*headers)
-The ``Vary`` header defines which request headers a cache mechanism should take
-into account when building its cache key.
+ The ``Vary`` header defines which request headers a cache mechanism should
take
+ into account when building its cache key.
-See :ref:`using vary headers <using-vary-headers>`.
+ See :ref:`using vary headers <using-vary-headers>`.
Modified: django/trunk/tests/regressiontests/decorators/tests.py
===================================================================
--- django/trunk/tests/regressiontests/decorators/tests.py 2011-04-28
01:47:21 UTC (rev 16114)
+++ django/trunk/tests/regressiontests/decorators/tests.py 2011-04-28
13:04:16 UTC (rev 16115)
@@ -2,11 +2,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
@@ -20,6 +20,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)
@@ -111,7 +112,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.
+ Refs #15637.
+ """
+ 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):
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.