I have a django site with a large customer base. I would like to give our customer service department the ability to alter normal user accounts, doing things like changing passwords, email addresses, etc. However, if I grant someone the built-in auth | user | Can change user
permission, they gain the ability to set the is_superuser
flag on any account, including their own. (!!!)
What's the best way to remove this option for non-superuser staff? I'm sure it involves subclassing django.contrib.auth.forms.UserChangeForm
and hooking it into my already-custom UserAdmin
object... somehow. But I can't find any documentation on how to do this, and I don't yet understand the internals well enough.
Full code for django 1.1 (limited to basic user information for staff (not superusers))
This approach was put together from several helpful tips on the web. In this case we are modifying UserAdmin so that, for non-superuser staff with user add/change permission, the only permissions and groups they can grant another user are the ones the staff member already has.
(for Django 1.11)
This should likewise be done for GroupAdmin if a user is given permission to change groups.
Great thanks to Clément. What I came up with when doing the same for my site is that I needed additionally to make all fields readonly for users you other than self. So basing on Clément's answer I addeed readonly fields and password field hiding when viewing not self
The below part of the accepted answer has a race condition where if two staff users try to access the admin form at the same time, one of them may get the superuser form.
To avoid this race condition (and in my opinion improve the overall quality of the solution), we can override the
get_fieldsets()
andget_readonly_fields()
methods directly:Not only this, they also gain the ability to give themselves any permissions one-by-one, same effect...
Well, not necessarily. The form you see in the change page of django's admin is dynamically created by the admin application, and based on
UserChangeForm
, but this class barely adds regex validation to theusername
field.A custom
UserAdmin
is the way to go here. Basically, you want to change thefieldsets
property to something like that :But the problem here is that this restriction will apply to all users. If this is not what you want, you could for example override
change_view
to behave differently depending on the permission of the users. Code snippet :