7

I am pretty new to Django (starting with 1.3). In building an app, I went with the new class-based generic views from day one, using a combination of the built in classes and subclassing them where I needed to add to the context.

Now my problem is, I need to go back to my views, and have them accessible only to logged in users. ALL the documentation I have found shows how to do this with the old functional generic views, but not with class-based.

Here is an example class:

class ListDetailView(DetailView):
    context_object_name = "list"

    def get_queryset(self):
        list = get_object_or_404(List, id__iexact=self.kwargs['pk'])
        return List.objects.all()

    def get_context_data(self, **kwargs):
        context = super(ListDetailView, self).get_context_data(**kwargs)
        context['subscriber_list'] = Subscriber.objects.filter(lists=self.kwargs['pk'])
        return context

How do I add authentication to django's new class-based views?

murgatroid99
  • 19,007
  • 10
  • 60
  • 95
  • possible duplicate of [How to use permission\_required decorators on django class-based views](http://stackoverflow.com/questions/6069070/how-to-use-permission-required-decorators-on-django-class-based-views) – meshy Jan 25 '14 at 10:05

3 Answers3

19

There's also the option of an authentication mixin, which you would derive your view class from. So using this mixin from brack3t.com:

class LoginRequiredMixin(object):

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(LoginRequiredMixin, self).dispatch(*args, **kwargs)

you could then create new "authentication required" views like this:

from django.views.generic import DetailView

class MyDetailView(LoginRequiredMixin, DetailView):
    ....

with no other additions needed. Feels very much like Not Repeating Oneself.

supervacuo
  • 9,072
  • 2
  • 44
  • 61
6

There's a section in the docs on decorating class-based views -- if you just want to use the old login_required etc., that's the way to go.

Ismail Badawi
  • 36,054
  • 7
  • 85
  • 97
  • 1
    i like using the dispatch method described in the same link, just to keep the urlconf cleaner. Another method is to subclass DetailView with the dispatch method and call it RestrictedDetailView then subclass RestrictedDetailView elsewhere – Dave Jul 08 '11 at 20:27
  • Note that the link above changed. See https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-the-class now – Olivier Berger Nov 05 '13 at 14:01
4

I am describing a method to decorate any ListView :

class MyListView(ListView):
    decorator = lambda x: x

    @method_decorator(decorator)
    def dispatch(self, request, *args, **kwargs):
       return super(MyListView, self).dispatch(request, *args, **kwargs)

After writing a class based view like this, you can directly insert any function based decorator into the url as so.

url(r'^myurl/$', MyListView.as_view(decorator=login_required))
acid_crucifix
  • 362
  • 2
  • 12