Django自定义UserAdmin设置权限时触发KeyError问题求助
Django Admin权限控制KeyError问题解决
问题概述
我是Python/Django初学者,想在CustomUserAdmin中实现权限控制:仅超级管理员可修改is_superuser、user_permissions、groups字段,普通用户/Staff用户登录时这些字段置灰。添加该逻辑前admin.py运行正常,但新增用户时触发KeyError,提示'is_superuser'不存在。
报错信息
KeyError at /admin/people/customuser/add/ 'is_superuser' Request Method: GET Request URL: http://localhost:8000/admin/people/customuser/add/ Django Version: 4.1.5 Exception Type: KeyError Exception Value: 'is_superuser' Exception Location: /cpp_base/people/admin.py, line 25, in get_form Raised during: django.contrib.auth.admin.add_view Python Executable: /usr/local/bin/python Python Version: 3.10.4
相关代码
admin.py代码片段
from django.contrib import admin from django.contrib.auth import get_user_model from django.contrib.auth.admin import UserAdmin from .forms import CustomUserCreationForm, CustomUserChangeForm from .models import JobTitle, JobSkill, SkillSet CustomUser = get_user_model() @admin.register(CustomUser) class CustomUserAdmin(UserAdmin): # 实现权限控制逻辑 def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) is_superuser = request.user.is_superuser if not is_superuser: form.base_fields["is_superuser"].disabled = True form.base_fields["user_permissions"].disabled = True form.base_fields["groups"].disabled = True return form add_form = CustomUserCreationForm form = CustomUserChangeForm model = CustomUser readonly_fields = ["last_login", "date_joined"] list_display = [ "username", "employed", "email", "job_title", "is_active", "is_staff", "is_superuser", ] fieldsets = ( ( None, { "fields": ( "username", "password", "first_name", "last_name", ) }, ), ( "Persönliche Information", { "fields": ("birth_date", "employed", "job_title", "skill_set"), }, ), ( "Adresse und Kontakt", { "classes": ("collapse",), "fields": ( "email", "mobile_number", "phone_number", "street_name", "street_number", "zip_code", "city", "country", ), }, ), ( "Berechtigungen", { "classes": ("collapse",), "fields": ( "is_active", "is_staff", "is_superuser", "groups", "user_permissions", ), }, ), ( "Anmelde Daten", { "classes": ("collapse",), "fields": ( "last_login", "date_joined", ), }, ), ) class JobTitleAdmin(admin.ModelAdmin): readonly_fields = ("created_at", "updated_at") admin.site.register(JobTitle, JobTitleAdmin) admin.site.register(JobSkill) admin.site.register(SkillSet)
表单代码
from django.contrib.auth import get_user_model from django.contrib.auth.forms import UserCreationForm, UserChangeForm class CustomUserCreationForm(UserCreationForm): class Meta: model = get_user_model() fields = ( "username", "email", "birth_date", "mobile_number", "phone_number", "job_title", "skill_set", ) class CustomUserChangeForm(UserChangeForm): class Meta: model = get_user_model() fields = ( "username", "email", "birth_date", "mobile_number", "phone_number", "job_title", "skill_set", )
问题原因
新增用户时,Django使用的是CustomUserCreationForm,而这个表单的Meta.fields里并没有包含is_superuser、groups、user_permissions这些字段,所以form.base_fields字典里不存在这些键,直接访问就会抛出KeyError。
解决方案
修改get_form方法,要么判断字段是否存在,要么仅在编辑用户(obj不为None)的场景下处理权限字段:
方案一:先检查字段是否存在
def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) is_superuser = request.user.is_superuser if not is_superuser: # 遍历字段,仅存在时设置禁用 for field_name in ["is_superuser", "user_permissions", "groups"]: if field_name in form.base_fields: form.base_fields[field_name].disabled = True return form
方案二:仅在编辑用户时处理
因为新增用户页面本来就不会显示这些权限字段,所以只需要在编辑用户时禁用:
def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) is_superuser = request.user.is_superuser # 只有编辑用户且当前用户不是超级管理员时,才禁用字段 if not is_superuser and obj is not None: form.base_fields["is_superuser"].disabled = True form.base_fields["user_permissions"].disabled = True form.base_fields["groups"].disabled = True return form
两种方案都能解决KeyError问题,同时实现预期的权限控制效果。
内容的提问来源于stack exchange,提问作者gomez_
相关产品推荐
相关产品推荐

