DaViDa
DaViDa

Reputation: 641

Django admin is_staff based on group

Is it possible to have is_staff selected by choosing a group? Let's say there are two groups: users, admins

When a new user is in the users group he is not staff, but if he is in the admins group he is staff.

Upvotes: 5

Views: 2619

Answers (4)

Noortheen Raja
Noortheen Raja

Reputation: 861

There are two place one should override to implement this behaviour

# inside any app's admin.py module

import types

from django.contrib import admin
from django.contrib.admin.forms import AdminAuthenticationForm

def has_permission(self, request):
    return request.user.is_active and (
        request.user.is_staff
        or request.user.groups.filter(name="grp").exists()
    )


class GrpAdminAuthenticationForm(AdminAuthenticationForm):
    def confirm_login_allowed(self, user):
        if user.groups.filter(name="grp").exists():
            user.is_staff = True
        super().confirm_login_allowed(user)


admin.site.login_form = GrpAdminAuthenticationForm
admin.site.has_permission = types.MethodType(has_permission, admin.site)

It will update the default admin.site object so one doesn't need to register to a custom object.

Upvotes: 0

ge0rg
ge0rg

Reputation: 1843

The is_staff property is primarily used by the admin interface. If you want to have an admin interface that's dependent on group membership, you can override AdminSite.has_permission() instead:

class GroupBasedAdminSite(admin.AdminSite):
    def has_permission(self, request):
        return request.user.is_active and request.user.groups.filter(name = 'admins').exists()

# override default admin site
admin.site = GroupBasedAdminSite()

You can also use the official override feature, or have a dedicated GroupBasedAdminSite hosted on a different path, in case you want to support different types of "admins".

Upvotes: 3

DaViDa
DaViDa

Reputation: 641

I managed to make it work by extending the UserAdmin class and in the get_form function I placed this with help of mascot6699's answer:

if obj.groups.filter(name="Administrator").exists():
    obj.is_staff = True
else:
    obj.is_staff = False

So whenever I place a user (with the admin menu) in the Administrator group it will check the is_staff option else it unchecks it.

Upvotes: 3

mascot6699
mascot6699

Reputation: 302

There is an easy way to do this define the following in your user model

@property
def is_staff(self):
    if self.is_staff == True or self.groups.filter(name="staff").exists()

Thus during admin login or any other time when you call from the user_object.is_staff You will be getting what you want on basis of groups too.

Upvotes: 4

Related Questions