I don't know of anywhere that has a line-by-line documentation of these decorators, but here's my take on it.
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
This function serves as the basis for Django's decorator based authentication.
It accepts a test function which will have the user passed to it to determine
whether or not that user has access to the decorated view.
def decorator(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
This chunk of code is just standard Python decorator stuff - if you understand
decorators there's not really anything to explain.
if test_func(request.user):
return view_func(request, *args, **kwargs)
Here the test function is called with the user. If the user passes the test
the original view function is immediately returned and no further action is
taken.
path = request.build_absolute_uri()
resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
Retrieve the current request's url and the login url. The login url can be
passed to the user_passes_test decorator or the default value in the Django
settings can be used.
# 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]
Retrieve the HTTP scheme (http or https) and the netloc (www.example.com plus
the port if applicable) from both the current url and the login url.
if ((not login_scheme or login_scheme == current_scheme) and
(not login_netloc or login_netloc == current_netloc)):
path = request.get_full_path()
If the HTTP scheme and the netloc for the two urls match then the path is set
to the relative url rather than the absolute url.
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(
path, resolved_login_url, redirect_field_name)
Redirect the request to the login page. redirect_to_login will send the user
to get logged in with a ?next= GET parameter equal to the current path.
return _wrapped_view
return decorator
Finishing decorator stuff.
login_required is just a shortcut for user_passes_test which already supplies the test_func - a simple function which checks the value of user.is_authenticated.
permission_required Does the same but takes the name of a permission or a list of permission names and checks that the user has those permissions. permission_required also has the added feature that you can pass raise_exception=True to raise a 403 instead of redirecting to the login url.