summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Michel <mail@raphaelmichel.de>2015-06-05 10:08:19 +0200
committerTim Graham <timograham@gmail.com>2015-06-08 13:44:39 -0400
commit39937de7e60052d3ffa9f07fdbb9262aced35d61 (patch)
treea49b4fd14a34fb0c68825f978031d56b390fe350
parent8b1f39a727be91aab40bdb37235718ed63ae1d50 (diff)
Fixed #24929 -- Allowed permission_required decorator to take any iterable
-rw-r--r--django/contrib/auth/decorators.py3
-rw-r--r--docs/releases/1.9.txt4
-rw-r--r--docs/topics/auth/default.txt7
-rw-r--r--tests/auth_tests/test_decorators.py10
4 files changed, 22 insertions, 2 deletions
diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py
index 9b2504b33c..6ab428e9cd 100644
--- a/django/contrib/auth/decorators.py
+++ b/django/contrib/auth/decorators.py
@@ -4,6 +4,7 @@ from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import PermissionDenied
from django.shortcuts import resolve_url
+from django.utils import six
from django.utils.decorators import available_attrs
from django.utils.six.moves.urllib.parse import urlparse
@@ -59,7 +60,7 @@ def permission_required(perm, login_url=None, raise_exception=False):
is raised.
"""
def check_perms(user):
- if not isinstance(perm, (list, tuple)):
+ if isinstance(perm, six.string_types):
perms = (perm, )
else:
perms = perm
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index a3fb56c6c0..55906864ef 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -114,6 +114,10 @@ Minor features
a deprecation warning in older versions and is no longer supported in
Django 1.9).
+* The permission argument of
+ :func:`~django.contrib.auth.decorators.permission_required()` accepts all
+ kinds of iterables, not only list and tuples.
+
:mod:`django.contrib.gis`
^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt
index 2df53816de..9e2d549fd1 100644
--- a/docs/topics/auth/default.txt
+++ b/docs/topics/auth/default.txt
@@ -580,7 +580,7 @@ The permission_required decorator
(i.e. ``polls.can_vote`` for a permission on a model in the ``polls``
application).
- The decorator may also take a list of permissions.
+ The decorator may also take an iterable of permissions.
Note that :func:`~django.contrib.auth.decorators.permission_required()`
also takes an optional ``login_url`` parameter. Example::
@@ -599,6 +599,11 @@ The permission_required decorator
(HTTP Forbidden) view<http_forbidden_view>` instead of redirecting to the
login page.
+ .. versionchanged:: 1.9
+
+ In older versions, the ``permission`` parameter only worked with
+ strings, lists, and tuples instead of strings and any iterable.
+
.. _applying-permissions-to-generic-views:
Applying permissions to generic views
diff --git a/tests/auth_tests/test_decorators.py b/tests/auth_tests/test_decorators.py
index ff1b1f52a2..61c1962a74 100644
--- a/tests/auth_tests/test_decorators.py
+++ b/tests/auth_tests/test_decorators.py
@@ -76,6 +76,16 @@ class PermissionsRequiredDecoratorTest(TestCase):
resp = a_view(request)
self.assertEqual(resp.status_code, 200)
+ def test_many_permissions_in_set_pass(self):
+
+ @permission_required({'auth.add_customuser', 'auth.change_customuser'})
+ def a_view(request):
+ return HttpResponse()
+ request = self.factory.get('/rand')
+ request.user = self.user
+ resp = a_view(request)
+ self.assertEqual(resp.status_code, 200)
+
def test_single_permission_pass(self):
@permission_required('auth.add_customuser')