Aman Sharma
Aman Sharma

Reputation: 287

Authentication for class based views in Django

class AdminView(generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

class AdminUpdateView(UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

There are two views in django which I have created and I want them to be accessed only when the admin/staff logins. How do I go about it?

Upvotes: 10

Views: 4956

Answers (5)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477824

You can use the UserPassesTestMixin [Django-doc] and LoginRequiredMixin [Django-doc] mixins, and specify as condition that the user should be an is_superuser. Since you need these twice, we can make first a composite mixin:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

class AdminStaffRequiredMixin(LoginRequiredMixin, UserPassesTestMixin):
    
    def test_func(self):
        return self.request.user.is_superuser or self.request.user.is_staff

Next you can add the mixin to your class-based views:

class AdminView(AdminStaffRequiredMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

class AdminUpdateView(AdminStaffRequiredMixin, UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

Upvotes: 19

Mirjahon Mirsaidov
Mirjahon Mirsaidov

Reputation: 1

You can use IsAdminUser permission by rest framework

from rest_framework import permissions

class AdminView(generic.ListView):
    permission_classes = (permissions.IsAdminUser, )
    ...

Upvotes: 0

Kenneth Murerwa
Kenneth Murerwa

Reputation: 888

If you want to use the LoginRequiredMixin, you still can. And it is much simpler. Just extend the LoginRequiredMixin in all you classes so that they are like this.

class AdminView(LoginRequiredMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

class AdminUpdateView(LoginRequiredMixin, UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

This ensures that the user is already logged in before allowing any operations. Then, check if the user is an admin by adding the following code to each of the classes;

def dispatch(self, request, *args, **kwargs):
    if not self.request.user.is_staff:
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

Your code should now look like this:

class AdminView(LoginRequiredMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

    def dispatch(self, request, *args, **kwargs):
        if not self.request.user.is_staff:
            raise PermissionDenied
        return super().dispatch(request, *args, **kwargs)

class AdminUpdateView(LoginRequiredMixin, UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

    def dispatch(self, request, *args, **kwargs):
        if not self.request.user.is_staff:
            raise PermissionDenied
        return super().dispatch(request, *args, **kwargs)

Upvotes: 0

Diego Vinícius
Diego Vinícius

Reputation: 2243

Use decorators, with @login_required you can tell this views will be only accesseed when user os logged in, you can pass parameters to it too or create one your own to validate if the logged user on the request can see or no your view

With Login Required

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
class AdminView(generic.ListView):
    ...

@login_required(login_url='/accounts/login/')
class AdminUpdateView(UpdateView):
    ...

https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-login-required-decorator

With Permission

from django.contrib.auth.decorators import permission_required

@permission_required('user.is_staff')
def my_view(request):
    ...

https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-permission-required-decorator

Upvotes: 2

neverwalkaloner
neverwalkaloner

Reputation: 47374

You can use UserPassesTestMixin:

from django.contrib.auth.mixins import UserPassesTestMixin

class AdminView(UserPassesTestMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

    def test_func(self):
        return self.request.user.is_staff or self.request.user.is_superuser

Upvotes: 2

Related Questions