我正在尝试定义一个装饰器来检查用户是否具有管理员某些权限:
def admin_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
actual_decorator = user_passes_test(
lambda u: u.is_staff and u.is_authenticated() and not Association.objects.filter(admins=u).exists(),
login_url=login_url,
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
return actual_decorator
目的是通过观点来使用它。特别是,我在基于类的视图中使用它:
class MyCBV(CreateView):
@method_decorator(admin_required)
def dispatch(self, request, *args, **kwargs):
return super(MyCBV, self).dispatch(request, *args, **kwargs)
问题是此视图是通过AJAX加载的,因此重定向不会发生。此外,即使用户身份验证失败,视图返回的HTTP状态也会成功,因此客户端(JS)无法确定操作何时成功。
我通常无法理解装饰器和Django身份验证,因此我的问题是:当身份验证修饰函数失败时,如何引发异常(最好是PermissionDenied
异常)?
答案 0 :(得分:1)
在Django 1.9+中,您可以使用UserPassesTestMixin
代替装饰器,并将raise_exception
设置为True
。
由于您使用的是不安全且过时的Django 1.4,因此您无法做到这一点。没有选项可以使user_passes_test
加注PermissionDenied
而不是重定向。您可以尝试检测JavaScript中的重定向,也可以查看user_passes_test
源代码并实现类似的返回所需响应的内容。