Django中对通过测试的用户进行限制访问的方法
限制访问可以基于某种权限,某些检查或者为login视图提供不同的位置,这些实现方式大致相同。
一般的方法是直接在视图的request.user上运行检查。例如,下面视图确认用户登录并是否有polls.can_vote权限:
defvote(request): ifrequest.user.is_authenticated()andrequest.user.has_perm('polls.can_vote')): #votehere else: returnHttpResponse("Youcan'tvoteinthispoll.")
并且Django有一个称为user_passes_test的简洁方式。它接受参数然后为你指定的情况生成装饰器。
defuser_can_vote(user): returnuser.is_authenticated()anduser.has_perm("polls.can_vote") @user_passes_test(user_can_vote,login_url="/login/") defvote(request): #Codeherecanassumealogged-inuserwiththecorrectpermission. ...
user_passes_test使用一个必需的参数:一个可调用的方法,当存在User对象并当此用户允许查看该页面时返回True。注意user_passes_test不会自动检查User
是否认证,你应该自己做这件事。
例子中我们也展示了第二个可选的参数login_url,它让你指定你的登录页面的URL(默认为/accounts/login/)。如果用户没有通过测试,那么user_passes_test将把用户重定向到login_url
既然检查用户是否有一个特殊权限是相对常见的任务,Django为这种情形提供了一个捷径:permission_required()装饰器。使用这个装饰器,前面的例子可以改写为:
fromdjango.contrib.auth.decoratorsimportpermission_required @permission_required('polls.can_vote',login_url="/login/") defvote(request): #...
注意,permission_required()也有一个可选的login_url参数,这个参数默认为'/accounts/login/'。
限制通用视图的访问
在Django用户邮件列表中问到最多的问题是关于对通用视图的限制性访问。为实现这个功能,你需要自己包装视图,并且在URLconf中,将你自己的版本替换通用视图:
fromdjango.contrib.auth.decoratorsimportlogin_required fromdjango.views.generic.date_basedimportobject_detail @login_required deflimited_object_detail(*args,**kwargs): returnobject_detail(*args,**kwargs)
当然,你可以用任何其他限定修饰符来替换login_required。