Skip to content

Instantly share code, notes, and snippets.

@tomfa
Last active September 4, 2017 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomfa/566dc5e5b476bbf107d4c7d23d820494 to your computer and use it in GitHub Desktop.
Save tomfa/566dc5e5b476bbf107d4c7d23d820494 to your computer and use it in GitHub Desktop.
django.contrib.auth.decorators @permission_required and @user_passes_test for class methods
def method_user_passes_test(
test_method, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
"""
This is a modified version of user_passes_test
(django.contrib.auth.decorators) that can be used on class methods.
"""
def decorator(view_method):
@wraps(view_method, assigned=available_attrs(view_method))
def _wrapped_view(self, request, *args, **kwargs):
if test_method(request.user):
return view_method(self, request, *args, **kwargs)
path = request.build_absolute_uri()
resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
# If the login url is the same scheme and net location then just
# use the path as the "next" url.
login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
current_scheme, current_netloc = urlparse(path)[:2]
if ((not login_scheme or login_scheme == current_scheme) and
(not login_netloc or login_netloc == current_netloc)):
path = request.get_full_path()
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(
path, resolved_login_url, redirect_field_name)
return _wrapped_view
return decorator
def method_permission_required(perm, login_url=None, raise_exception=False):
"""
This is a modified version of permission_required
(django.contrib.auth.decorators) that can be used on class methods.
"""
def check_perms(user):
if isinstance(perm, six.string_types):
perms = (perm, )
else:
perms = perm
# First check if the user has the permission (even anon users)
if user.has_perms(perms):
return True
# In case the 403 handler should be called raise the exception
if raise_exception:
raise PermissionDenied
# As the last resort, show the login form
return False
return method_user_passes_test(check_perms, login_url=login_url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment