Как использовать пользовательскую форму ModelForm в админке пользователя
Я пытаюсь ограничить возможности стандартного пользователя в админке приложения Django, чтобы избежать возможности эскалации привилегий.User
Я попробовал подход, упомянутый в документации: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_form
class UserAdmin(BaseUserAdmin):
form = UserForm
inlines = (UserProfileInline,)
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs["form"] = SuperUserForm
return super().get_form(request, obj, **kwargs)
class UserForm(ModelForm):
class Meta:
model = User
exclude = ("is_superuser",) # it is just an example
class SuperUserForm(ModelForm):
class Meta:
model = User
fields = "__all__
К сожалению, это приводит к такой ошибке:
"Key 'is_superuser' not found in 'UserForm'. Choices are: date_joined, email, first_name, groups, is_active, is_staff, last_login, last_name, password, user_permissions, username."
Если бы я решил исключить "группы":
"Key 'groups' not found in 'UserForm'. Choices are: date_joined, email, first_name, is_active, is_staff, is_superuser, last_login, last_name, password, user_permissions, username."
В итоге у меня получился совершенно другой подход:
class UserAdmin(BaseUserAdmin):
def has_change_permission(self, request, obj=None):
if obj != request.user and not request.user.is_superuser:
return False
return True
def changelist_view(self, request, extra_context=None):
if request.user.is_superuser:
return super().changelist_view(request, extra_context)
return HttpResponseRedirect(
reverse(
"admin:%s_%s_change" % (self.model._meta.app_label, self.model._meta.model_name),
args=(request.user.id,),
)
)
def get_fieldsets(self, request, obj=None):
fieldsets = list(super().get_fieldsets(request, obj))
if request.user.is_superuser:
return fieldsets
return [
(None, {"fields": ("username", "password")}),
("Personal info", {"fields": ("first_name", "last_name", "email")}),
]
Я не знаю, является ли это "по-джанговски", но кажется, что это работает так, как ожидалось.