Accessing a context object in a Django class-based generic view

Asterism picture Asterism · Apr 28, 2011 · Viewed 10.8k times · Source

I'm using a DetailView to view a Project object, and I would like to be able to access the Project object being viewed in order to pass it to a decorator, something like this:

class ProjectDetailView(DetailView):
    context_object_name = "project"
    model = Project

    @method_decorator(membership_required(project))
    def dispatch(self, *args, **kwargs):
        return super(ProjectDetailView, self).dispatch(*args, **kwargs)

However, passing in "project" or "object" to the decorator gives me an "object", not a Project instance. How can I get that Project instance so my decorator function can work with it?

Answer

Ivan Virabyan picture Ivan Virabyan · Apr 28, 2011

Object is retrieved inside a dispatch() method, so your decorator can not use it. You may check membership inside of an overriden get() method:

class ProjectDetailView(DetailView):
    context_object_name = "project"
    model = Project

    def get(self, request, **kwargs):
        self.object = self.get_object()
        if not self.object.is_member(self.request.user):
            return HttpResponseRedirect('/') # or something else
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

If you want to stick to decorator, you'll have to retrive object from database within your decorator, based on args (id or slug) to view. But you will be retrieving object from database twice, first in your decorator, and then within a view.