login_required decorator on a class based view in django

5.3k Views Asked by At

I have a working class based view. But when adding @login_required I get the error:

AttributeError: 'function' object has no attribute 'as_view'

Something is happening to the ResultListView here:

from django.urls import path
from .views import ResultListView


urlpatterns = [
    path('meetings/', ResultListView.as_view(), name='meetings'),
]

My views.py:

@login_required
class ResultListView(ListView):
    template_name = ...

    def get_queryset(self):
        return Result.objects.filter(rider__user=self.request.user)

Which is all working fine until I put the decorator in. Very confused now, I don't see why ResultListView should loose its attributes when sending it through the decorator.

1

There are 1 best solutions below

4
willeM_ Van Onsem On

The @login_required decorator only decorates functions, not classes, you can make use of a mixin, or decorate the function that is the result of the .as_view() call.

Option 1: Using the LoginRequiredMixin

You can make use of the LoginRequiredMixin [Django-doc] that you need to put before the ListView in the parent classes:

from django.contrib.auth.mixins import LoginRequiredMixin

class ResultListView(LoginRequiredMixin, ListView):
    template_name = …

    def get_queryset(self):
        return Result.objects.filter(rider__user=self.request.user)

Option 2: decorate the .as_view() result

An alternative is to decorate the outcome of the .as_view, which is indeed a function:

from django.urls import path
from .views import ResultListView
from django.contrib.auth.decorators import login_required

urlpatterns = [
    path('meetings/', login_required(ResultListView.as_view()), name='meetings'),
]