我正在尝试将基于角色的权限实现到我的应用程序中。我有一个decorator role_required,我可以传递一组用户角色,只有具有该角色的用户才能访问该视图。我已经为用户正确分配了角色,但现在我收到了AttributeError,声明'Role' object has no attribute '__name__'
views.py
档案:
m_role_required = method_decorator(role_required)
class AddProposal(FormView):
@m_role_required(roles.space_admin)
def dispatch(self, *args, **kwargs):
return super(AddProposal, self).dispatch(*args, **kwargs)
装饰者role_required
:
from django.contrib.auth.decorators import user_passes_test
def role_required(*roles):
def check_role(user):
return getattr(user, 'role', None) in roles
return user_passes_test(check_role)
Role
类:
class Roles(object):
_roles_dict = None
@property
def roles_dict(self):
if self._roles_dict is None:
self._roles_dict = {}
for item in self._config:
if isinstance(item, basestring):
# An item like 'manager'
self._roles_dict[item] = None
else:
# Anything else
raise ImproperlyConfigured(_INCORRECT_ARGS)
return self._roles_dict
@property
def choices(self):
return [(role, role) for role in self.roles_dict.keys()]
def __init__(self, config=None):
self._config = config or getattr(settings, 'USER_ROLES', ())
def __getattr__(self, name):
if name in self.roles_dict.keys():
return Role(name=name)
else:
raise AttributeError("No such role exists '%s'" % name)
roles = Roles()
我无法找出导致此错误的原因。谁能帮忙。让我用这个添加回溯,
环境:
Request Method: GET
Request URL: http://127.0.0.1:8000/en-gb/spaces/bithin/proposal/add/
Traceback:
48. class AddProposal(FormView):
File "/home/bithin/gsoc/week3/e-cidadania/src/apps/ecidadania/proposals/views.py" in AddProposal
78. @m_role_required(roles.space_admin)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _dec
34. update_wrapper(_wrapper, func)
File "/usr/lib/python2.7/functools.py" in update_wrapper
33. setattr(wrapper, attr, getattr(wrapped, attr))
Exception Type: AttributeError at /en-gb/spaces/bithin/proposal/add/
Exception Value: 'Role' object has no attribute '__name__'
答案 0 :(得分:5)
查看django.utils.decorators.method_decorator
的代码。它返回的方法装饰器不能接受进一步的参数保存为实际的装饰功能。此函数的属性(包括其__name__
)通过functools.update_wrapper
以通常的Python方式复制。您收到此错误是因为您传递了Role
对象而不是函数。
换句话说,你需要像这样重写你的观点:
space_admin_required = method_decorator(role_required(roles.space_admin))
class AddProposal(FormView):
@space_admin_required
def dispatch(self, *args, **kwargs):
return super(AddProposal, self).dispatch(*args, **kwargs)
答案 1 :(得分:1)
这是Why do python instances have no __name__ attribute?
的潜在副本简答:类的名称存储在类中,并且不能直接用于实例。
您可以通过myinstance.__class__.__name__
访问实例的类名。