'Role' object has no attribute '__name__'
django, django-generic-views, django-views, python
Solution
Have a look at the code for `django.utils.decorators.method_decorator`. The method decorator it returns cannot accept further parameters save for the actual function to decorate. Properties of this function, including its `__name__`, are copied over via `functools.update_wrapper`, in the usual Python fashion. You get this error because you pass a `Role` object instead of a function.
In other words, you need to rewrite your view like this:
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)
Problem
I am trying to implement role based permission into my application. I have a decorator role_required into which I can pass a set of user roles and only those user with that role can access that view. I have properly assigned roles to the user but, now I am getting AttributeError stating that `'Role' object has no attribute '__name__'` `views.py` file: ``` 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) ``` The decorator `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) ``` The `Role` class: ``` 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() ``` I am not able to find out why this error is being raised. Can anyone help. Let me add the traceback with this, Environment: ``` 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__' ```