How to write a decorator for a class based view -- permision based on object from view
django, django-class-based-views
Solution
Use `method_decorator` on the dispatch() method: https://docs.djangoproject.com/en/dev/topics/class-based-views/#decorating-class-based-views
from django.utils.decorators import method_decorator
class ClassBasedView(View):
@method_decorator(rules_permission_required)
def dispatch(self, *args, **kwargs):
return super(ClassBasedView, self).dispatch(*args, **kwargs)
Or you could decorate the output of the `as_view` class method, either in your url config (as described in the link above), or by saving the instance into a variable.
class ClassBasedView(View):
def dispatch(self, *args, **kwargs):
return super(ClassBasedView, self).dispatch(*args, **kwargs)
class_based_view = rules_permission_required(ClassBasedView.as_view())
Though I'm not quite sure whether the last example could cause thread safety problems (depends on how Django handles the instances). The best way is probably to stick with the `method_decorator`.
Problem
right now I'm using this app for permission checking: django-rules However it hasn't been updated for over a year now and there's no decorator for the "new" (since django 1.3) class based views. I would like to be able to use at the urls.py like this: ``` url(r'^casos/(?P<pk>\d+)/editar/$', rules_permission_required('lawsuits.logical_check', raise_exception=True)(CaseUpdateView.as_view()), name='case_edit'), ``` I can't figure out how to get the object from the class based view from the decorator. Do you guys have any idea? Here's what I have so far: ``` from django.utils.decorators import available_attrs def rules_permission_required(perm, queryset=None, login_url=None, raise_exception=False): def wrapper(view_func): @wraps(view_func, assigned=available_attrs(view_func)) def inner(request, *args, **kwargs): #view_func is the class based view -> <function MyEditView at 0x94e54c4> print view_func.get_object() # doesnt work print view_func(request, *args, **kwargs).get_object() # doesnt work either #any ideas? if not request.user.has_perm(perm, obj=obj): return redirect_to_login(request, login_url, raise_exception) return view_func(request, *args, **kwargs) return inner return wrapper ``` Many thanks in advance!