diff --git a/django/views/decorators/http.py b/django/views/decorators/http.py
index dc90cc3..054dc57 100644
|
a
|
b
|
require_GET.__doc__ = "Decorator to require that a view only accept the GET meth
|
| 48 | 48 | require_POST = require_http_methods(["POST"]) |
| 49 | 49 | require_POST.__doc__ = "Decorator to require that a view only accept the POST method." |
| 50 | 50 | |
| | 51 | require_safe = require_http_methods(["GET", "HEAD"]) |
| | 52 | require_safe.__doc__ = "Decorator to require that a view only accept safe methods: GET and HEAD." |
| | 53 | |
| 51 | 54 | def condition(etag_func=None, last_modified_func=None): |
| 52 | 55 | """ |
| 53 | 56 | Decorator to support conditional retrieval (or change) for a view |
diff --git a/docs/topics/http/decorators.txt b/docs/topics/http/decorators.txt
index 09ffecb..d7d2803 100644
|
a
|
b
|
various HTTP features.
|
| 10 | 10 | Allowed HTTP methods |
| 11 | 11 | ==================== |
| 12 | 12 | |
| 13 | | The following decorators in :mod:`django.views.decorators.http` can be used to |
| 14 | | restrict access to views based on the request method. |
| | 13 | The decorators in :mod:`django.views.decorators.http` can be used to restrict |
| | 14 | access to views based on the request method. |
| 15 | 15 | |
| 16 | 16 | .. function:: require_http_methods(request_method_list) |
| 17 | 17 | |
| 18 | | This decorator is used to ensure that a view only accepts particular request |
| 19 | | methods. Usage:: |
| 20 | | |
| 21 | | from django.views.decorators.http import require_http_methods |
| | 18 | Decorator to require that a view only accept particular request |
| | 19 | methods. Usage:: |
| | 20 | |
| | 21 | from django.views.decorators.http import require_http_methods |
| | 22 | |
| | 23 | @require_http_methods(["GET", "POST"]) |
| | 24 | def my_view(request): |
| | 25 | # I can assume now that only GET or POST requests make it this far |
| | 26 | # ... |
| | 27 | pass |
| | 28 | |
| | 29 | Note that request methods should be in uppercase. |
| | 30 | |
| | 31 | .. function:: require_GET() |
| 22 | 32 | |
| 23 | | @require_http_methods(["GET", "POST"]) |
| 24 | | def my_view(request): |
| 25 | | # I can assume now that only GET or POST requests make it this far |
| 26 | | # ... |
| 27 | | pass |
| | 33 | Decorator to require that a view only accept the GET method. |
| 28 | 34 | |
| 29 | | Note that request methods should be in uppercase. |
| | 35 | .. function:: require_POST() |
| 30 | 36 | |
| 31 | | .. function:: require_GET() |
| | 37 | Decorator to require that a view only accept the POST method. |
| 32 | 38 | |
| 33 | | Decorator to require that a view only accept the GET method. |
| | 39 | .. function:: require_safe() |
| 34 | 40 | |
| 35 | | .. function:: require_POST() |
| | 41 | .. versionadded:: Development version |
| 36 | 42 | |
| 37 | | Decorator to require that a view only accept the POST method. |
| | 43 | Decorator to require that a view only accept the GET and HEAD methods. |
| | 44 | These methods are commonly considered "safe" because they should not have |
| | 45 | the significance of taking an action other than retrieving the requested |
| | 46 | resource. |
| | 47 | |
| | 48 | .. note:: |
| | 49 | Django will automatically strip the content of responses to HEAD |
| | 50 | requests while leaving the headers unchanged, so you may handle HEAD |
| | 51 | requests exactly like GET requests in your views. Since some software, |
| | 52 | such as link checkers, rely on HEAD requests, you might prefer |
| | 53 | using ``require_safe`` instead of ``require_GET``. |
| 38 | 54 | |
| 39 | 55 | Conditional view processing |
| 40 | 56 | =========================== |
diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py
index dac4029..52a1ecd 100644
|
a
|
b
|
from functools import wraps
|
| 2 | 2 | |
| 3 | 3 | from django.contrib.auth.decorators import login_required, permission_required, user_passes_test |
| 4 | 4 | from django.contrib.admin.views.decorators import staff_member_required |
| 5 | | from django.http import HttpResponse, HttpRequest |
| | 5 | from django.http import HttpResponse, HttpRequest, HttpResponseNotAllowed |
| 6 | 6 | from django.utils.decorators import method_decorator |
| 7 | 7 | from django.utils.functional import allow_lazy, lazy, memoize |
| 8 | 8 | from django.utils.unittest import TestCase |
| 9 | | from django.views.decorators.http import require_http_methods, require_GET, require_POST |
| | 9 | from django.views.decorators.http import require_http_methods, require_GET, require_POST, require_safe |
| 10 | 10 | from django.views.decorators.vary import vary_on_headers, vary_on_cookie |
| 11 | 11 | from django.views.decorators.cache import cache_page, never_cache, cache_control |
| 12 | 12 | |
| … |
… |
fully_decorated.anything = "Expected __dict__"
|
| 20 | 20 | fully_decorated = require_http_methods(["GET"])(fully_decorated) |
| 21 | 21 | fully_decorated = require_GET(fully_decorated) |
| 22 | 22 | fully_decorated = require_POST(fully_decorated) |
| | 23 | fully_decorated = require_safe(fully_decorated) |
| 23 | 24 | |
| 24 | 25 | # django.views.decorators.vary |
| 25 | 26 | fully_decorated = vary_on_headers('Accept-language')(fully_decorated) |
| … |
… |
class DecoratorsTest(TestCase):
|
| 111 | 112 | my_view_cached4 = cache_page()(my_view) |
| 112 | 113 | self.assertEqual(my_view_cached4(HttpRequest()), "response") |
| 113 | 114 | |
| | 115 | def test_require_safe_accepts_only_safe_methods(self): |
| | 116 | """ |
| | 117 | Test for the require_safe decorator. |
| | 118 | A view returns either a response or an exception. |
| | 119 | Refs #15637. |
| | 120 | """ |
| | 121 | def my_view(request): |
| | 122 | return HttpResponse("OK") |
| | 123 | my_safe_view = require_safe(my_view) |
| | 124 | request = HttpRequest() |
| | 125 | request.method = 'GET' |
| | 126 | self.assertTrue(isinstance(my_safe_view(request), HttpResponse)) |
| | 127 | request.method = 'HEAD' |
| | 128 | self.assertTrue(isinstance(my_safe_view(request), HttpResponse)) |
| | 129 | request.method = 'POST' |
| | 130 | self.assertTrue(isinstance(my_safe_view(request), HttpResponseNotAllowed)) |
| | 131 | request.method = 'PUT' |
| | 132 | self.assertTrue(isinstance(my_safe_view(request), HttpResponseNotAllowed)) |
| | 133 | request.method = 'DELETE' |
| | 134 | self.assertTrue(isinstance(my_safe_view(request), HttpResponseNotAllowed)) |
| | 135 | |
| 114 | 136 | |
| 115 | 137 | # For testing method_decorator, a decorator that assumes a single argument. |
| 116 | 138 | # We will get type arguments if there is a mismatch in the number of arguments. |