from django.contrib.auth.decorators import login_required from django.urls import reverse from django.http import HttpResponseRedirect from django.core.exceptions import PermissionDenied from django.contrib import messages try: from functools import wraps except ImportError: # pragma: no cover from django.utils.functional import wraps REDIRECT_FIELD_NAME = None default_message = "Please log in, in order to see the requested page." def user_passes_test(test_func, message=default_message, login_url=None, redirect_field_name=None): """ Decorator for views that checks that the user passes the given test, setting a message in case of no success. The test should be a callable that takes the user object and returns True if the user passes. """ def decorator(view_func): # @wraps(view_func, assigned=available_attrs(view_func)) def _wrapped_view(request, *args, **kwargs): if request.user.is_anonymous: url = reverse('login')+'?next='+request.path return HttpResponseRedirect(url) if not test_func(request.user): messages.error(request, message) return HttpResponseRedirect(login_url) return view_func(request, *args, **kwargs) return _wrapped_view return decorator def login_required_message(function=None, message=default_message): # pragma: no cover """ Decorator for views that checks that the user is logged in, redirecting to the log-in page if necessary. """ actual_decorator = user_passes_test( lambda u: u.is_authenticated, message=message, ) if function: return actual_decorator(function) return actual_decorator