简体   繁体   中英

How to restrict access for staff users to see only their information in Django admin page?

I have created a custom Django admin page. I have two types of users who can access admin page (staff user and superuser). Superuser can see all the users and can change their settings. He can also add or delete users. The staff user can only see their settings and can change some of them. I currently have a problem that staff users can see all users of the web application and can add or delete them. I restricted staff users to see certain settings but could not change it.

I do not know how to restrict staff users to see only their settings.

Here is my code: Admin.py

from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

from .forms import UserAdminChangeForm, UserAdminCreationForm
from .models import UpLoadFile

User = get_user_model()

admin.site.site_header = 'SRC Orkestracija'
admin.site.index_title = 'Administration'
admin.site.register(UpLoadFile)


class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserAdminChangeForm
    add_form = UserAdminCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('username', 'superuser', 'active', 'staff')
    list_filter = ('superuser', 'active', 'staff')
    readonly_fields = [
        'last_login'
    ]
    actions = [
        'activate_users',
    ]
    filter_horizontal = ('user_permissions', 'groups')

    fieldsets = (
        (None, {'fields': ('username', 'password', 'config_file')}),
        ('Permissions', {'fields': ('superuser', 'active', 'staff', 'groups', 'user_permissions')}),
        ('Important dates', {'fields': ('last_login',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'password1', 'password2', 'config_file')}
         ),
    )
    search_fields = ('username',)
    ordering = ('username',)

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        is_superuser = request.user.is_superuser
        disabled_fields = set()

        if not is_superuser:
            disabled_fields |= {
                'username',
                'active',
                'superuser',
                'staff',
                'groups',
                'user_permissions'
            }
            if (
                    not is_superuser
                    and obj is not None
                    and obj == request.user
            ):
                disabled_fields |= {
                    'username',
                    'active',
                    'superuser',
                    'staff',
                    'groups',
                    'user_permissions'
                }

            for f in disabled_fields:
                if f in form.base_fields:
                    form.base_fields[f].disabled = True
        return form

    def activate_users(self, request, queryset):
        is_superuser = request.user.is_superuser
        if is_superuser:
            cnt = queryset.filter(active=False).update(active=True)
            self.message_user(request, 'Activated {} users.'.format(cnt))

    activate_users.short_description = 'Activate Users'


admin.site.register(User, UserAdmin)

Models.py:

class UserManager(BaseUserManager):
    def create_user(self, username, config_file, password=None, is_active=True, is_staff=False, is_superuser=False):
        if not username:
            raise ValueError("User must have username!")
        if not password:
            raise ValueError("User must have password!")
        if not config_file:
            raise ValueError("Select config file!")
        user_obj = self.model(
            username=username,
        )
        user_obj.config_file = config_file
        user_obj.staff = is_staff
        user_obj.superuser = is_superuser
        user_obj.active = is_active
        user_obj.set_password(password)
        user_obj.save(using=self._db)
        return user_obj

    def create_staffuser(self, username, config_file, password=None):
        user = self.create_user(
            username=username,
            config_file=config_file,
            password=password,
            is_staff=True
        )
        return user

    def create_superuser(self, username, config_file, password=None):
        user = self.create_user(
            username=username,
            config_file=config_file,
            password=password,
            is_staff=True,
            is_superuser=True
        )
        return user


class CustomUser(AbstractBaseUser, PermissionsMixin):
    class Meta:
        verbose_name = "User"
        verbose_name_plural = "Users"

    OPTIONS = (
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4'),
    )
    username = models.CharField(unique=True, max_length=255)
    active = models.BooleanField(default=True,
                                 help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.')
    staff = models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.')
    superuser = models.BooleanField(default=False,
                                    help_text='Designates that this user has all permissions without explicitly assigning them.')
    config_file = models.CharField(choices=OPTIONS, max_length=255)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['config_file']

    object = UserManager()

    def __str__(self):
        return self.username

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_lable):
        return True

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_superuser(self):
        return self.superuser

    @property
    def is_active(self):
        return self.active


def path(user, filename):
    return os.path.join(str(user))

I will appreciate any help or instructions how can I add this feature.

You can set superusers to only have add/delete permissions in the admin class.

class UserAdmin(BaseUserAdmin):
    ...
    def has_add_permission(self, request, obj=None):
        return request.user.is_superuser

    def has_delete_permission(self, request, obj=None):
        return request.user.is_superuser

Note the above is also achievable by not granting the add or delete permissions to any group or user in the admin interface.

The following will only allow users to change all users if they are a superuser. Else they will only be able to change their own user.

    def has_change_permission(self, request, obj=None):
        return request.user.is_superuser or (obj and obj.id == request.user.id)

And if you want them to be able to see the user list page with only their user visible you can modify get_queryset

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        user = request.user
        return qs if user.is_superuser else qs.filter(id=user.id)

In your template:

{% if request.user.is_superuser %}
<!-- Only superusers can view things in here -->
{% endif %}

In your view, you also will have to control what can be edited and what cannot be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM