Django Admin权限配置:普通管理员可访问非User模型的方案
问题描述
我正在开发一个校园网站,需要在Django Admin中实现以下权限配置:
- 超级管理员(拥有
is_staff和is_superuser权限)可以创建、管理所有用户 - 普通管理员(仅拥有
is_staff权限)无法访问User模型,但能正常操作其他业务模型
目前普通管理员登录Admin后会收到「You don’t have permission to view or edit anything.」错误,超级管理员操作一切正常,需要调整权限配置实现需求。
managers.py
from django.contrib.auth.models import BaseUserManager class CustomUserManager(BaseUserManager): def _create_user(self, username, position, password, is_staff, is_superuser, **extra_fields): if not username: raise ValueError("Вы не ввели username!") if not password: raise ValueError("Вы не ввели пароль!") user = self.model( username=username, position=position, is_active=True, is_staff=is_staff, is_superuser=is_superuser, **extra_fields ) user.set_password(password) user.save(using=self._db) return user def create_user(self, username, position="Администратор", password=None, **extra_fields): return self._create_user(username, position, password, is_staff=False, is_superuser=False, **extra_fields) def create_superuser(self, username, password=None, **extra_fields): return self._create_user( username, position="Главный администратор", password=password, is_staff=True, is_superuser=True, **extra_fields )
models.py
from django.contrib.auth.models import ( AbstractBaseUser, PermissionsMixin, ) from django.db import models from .managers import CustomUserManager POSITION = [ ('Главный администратор', 'Главный администратор'), ('Администратор', 'Администратор'), ] class User(AbstractBaseUser, PermissionsMixin): id = models.AutoField(primary_key=True, unique=True) username = models.CharField(max_length=24, unique=True, verbose_name="Имя пользователя (на английском)") position = models.CharField(choices=POSITION, default="Администратор", blank=False, null=False, max_length=21) is_active = models.BooleanField(default=True, verbose_name="Активность") is_staff = models.BooleanField(default=False, verbose_name="Администратор") is_superuser = models.BooleanField(default=False, verbose_name="Главный администратор") USERNAME_FIELD = 'username' REQUIRED_FIELDS = [] objects = CustomUserManager() class Meta: verbose_name = "Администратор" verbose_name_plural = "Администраторы" def __str__(self): return self.username def save(self, *args, **kwargs): if self.position == "Главный администратор": self.is_superuser = True self.is_staff = True elif self.position == "Администратор": self.is_superuser = False self.is_staff = True super().save(*args, **kwargs)
forms.py
from django import forms from django.contrib.auth.forms import UserChangeForm from .models import User class CustomUserChangeForm(UserChangeForm): password = forms.CharField( widget=forms.PasswordInput(), required=False, help_text="Оставьте это поле пустым, если не хотите менять пароль." ) class Meta: model = User fields = '__all__' def save(self, commit=True): user = super().save(commit=False) password = self.cleaned_data.get('password') if password: user.set_password(password) else: user.password = User.objects.get(id=user.id).password if commit: user.save() return user
admin.py
from django.contrib import admin from .models import User from .forms import CustomUserChangeForm @admin.register(User) class UserAdmin(admin.ModelAdmin): form = CustomUserChangeForm list_display = ('username', 'position') ordering = ('username',) fieldsets = ( (None, {'fields': ('username', 'password')}), ('Position', {'fields': ('position', )}), )
解决方案
1. 限制User模型的Admin访问权限
修改admin.py中的UserAdmin类,重写权限控制方法,仅允许超级管理员访问User模型:
from django.contrib import admin from .models import User from .forms import CustomUserChangeForm @admin.register(User) class UserAdmin(admin.ModelAdmin): form = CustomUserChangeForm list_display = ('username', 'position') ordering = ('username',) fieldsets = ( (None, {'fields': ('username', 'password')}), ('Position', {'fields': ('position', )}), ) # 仅超级管理员能查看User模型 def has_view_permission(self, request, obj=None): return request.user.is_superuser # 仅超级管理员能添加用户 def has_add_permission(self, request): return request.user.is_superuser # 仅超级管理员能修改用户 def has_change_permission(self, request, obj=None): return request.user.is_superuser # 仅超级管理员能删除用户 def has_delete_permission(self, request, obj=None): return request.user.is_superuser
2. 给普通管理员分配其他模型权限
登录超级管理员账号,进入用户管理页面:
- 找到目标普通管理员,进入用户详情页切换到「权限」标签
- 手动勾选该用户需要操作的业务模型对应权限(如
view_xxx、add_xxx、change_xxx、delete_xxx) - 或创建权限组,批量分配权限后将普通管理员加入组中
3. 验证效果
用普通管理员账号登录Django Admin:
- 不会看到User模型入口
- 可正常访问并操作已分配权限的业务模型
- 不再出现权限不足的错误提示
内容的提问来源于stack exchange,提问作者Шахнур Калыбеков
相关产品推荐
相关产品推荐

