Django Class-Based Generic Views and Authentication
Asked Answered
A

3

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?

Ai answered 8/7, 2011 at 19:26 Comment(1)
possible duplicate of How to use permission_required decorators on django class-based viewsFloatplane
K
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.

Kelula answered 24/4, 2012 at 19:41 Comment(1)
Nice! I prefer this approach.Ai
G
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.

Gregarine answered 8/7, 2011 at 19:54 Comment(2)
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 elsewhereSethrida
Note that the link above changed. See docs.djangoproject.com/en/dev/topics/class-based-views/intro/… nowDannielledannon
M
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))
Mccord answered 29/3, 2012 at 21:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.