from django.contrib.auth.decorators import login_required
def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None): actual_decorator = user_passes_test( lambda u: u.is_authenticated, login_url=login_url, redirect_field_name=redirect_field_name ) if function: return actual_decorator(function) return actual_decorator可以看出这个函数可以传递两个参数,我们这个函数做一下简单的分析:login_url 表示若为匿名用户访问时重定向的 URL,这里一般指定的都是登录页面的 URL 路径,默认的登录页需要在配置文件通过 LOGIN_URL 指定,然后通过使用以下方式进行调用 settings.py.LOGIN_URL;redirect_field_name 默认值为 next,作为 GET 的请求参数即参训字符串的形式,它的格式如下:
127.0.0.1:8000/login/?next=/index/add_book/1
这个参数用于登录后直接跳回到原先访问的视图。上述源码中可以看出该方法的实现核心是调用了 user_passes_test 方法。它需要传递三个参数,分析它的部分源码。如下所示:def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): def decorator(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): #测试函数,通过后执行对应的视图函数 if test_func(request.user): return view_func(request, *args, **kwargs) path = request.build_absolute_uri() #返回请求完成的URL #获取登录页指定的URL 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] #如果登录页的 URL与path的协议,域都相同则执行下面代码 if ((not login_scheme or login_scheme == current_scheme) and (not login_netloc or login_netloc == current_netloc)): #获取视图的全路径,返回 HttpResponseRedirect 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从 user_passes_test 的实现可以看出,它首先会判断 request.user.is_authenticated 是否会返回 True,如果成立,则会执行视图函数。否则,将重定向到登录页面。
from django.contrib.auth.decorators import login_required @login_required def search_title_views(request): pass如果在用户未登录的情况下访问这个视图的话,那么它将会跳转到登录页,需要注意的是由于这里没有指定 login_url,因此在配置文件中的 LOGIN_URL 要设置正确。
def permission_required(perm, login_url=None, raise_exception=False): """ 用于检查用户是否启用了特定权限的视图的装饰器,必要时可重定向到登录页。 如果给定了raise_exception参数,则会引发PermissionDenied异常。 """ def check_perms(user): #如果指定权限是字符串,则将其放在元组中 if isinstance(perm, str): perms = (perm,) else: perms = perm #校验用户是否具有指定的权限 if user.has_perms(perms): return True # In case the 403 handler should be called raise the exception if raise_exception: raise PermissionDenied #最终没有通过校验返回 False return False #check_perms 即为 user_passes_test中的测试函数 return user_passes_test(check_perms, login_url=login_url)这个函数接受三个参数,它们的介绍如下:
@permission_required("index.can_view_book")#也可校验多个权限,在方法内添加即可 def book_add_views(request): pass我们可以这样理解,如果访问用户没有被授予 index.can_view_book 权限,就会跳转到登录页。这样不仅需要当前用户是已登庄状态,还需要用户拥有 can_view_book 的权限。
本文链接:http://task.lmcjl.com/news/16953.html