Understanding Python Classes or Customising the Django UserAdmin model
I'm attempting to override some of the behaviour of the Django UserAdmin model. Particularly, I'd like to hide the 'superuser' field from non-superusers.
So, my approach is this:
class ModelAdmin(BaseModelAdmin):
"Encapsulates all admin options and functionality for a given model."
# ...
def has_change_permission(self, request, obj=No开发者_如何学Cne):
"""
Returns True if the given request has permission to change the given
Django model instance.
If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.
"""
opts = self.opts
return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())
#...
Based on what I've found in ModelAdmin
class UserAdmin(UserAdmin):
"""
... my customised UserAdmin
"""
# adding a new method
def is_superuser(self, request):
"Returns True if the given user is a superuser."
return request.user.is_superuser
# then elsewhere 'hopefully' show a slightly different fieldset
# the following, of course, doesn't work.
fieldsets = (
(None, {
'fields': (
("first_name", "last_name"),
("email", "password"),
"is_staff",
"is_active",
"is_superuser" if self.is_superuser() else None
)
}),
('Groups', {
'fields': (
'groups',
)
}),
('Meta', {
'classes': ('collapse',),
'fields': (
'username',
"last_login",
"date_joined"
)
})
)
So, my questions are:
- How do I create a
def
within my new custom UserAdmin class, such as above, and how do I call it? (How do I know when I'm in the right context to do so) - Part 2 (bonus): how can I succinctly include/exclude the 'is_superuser' field in the form, as the psuedo code above is suggesting?
Kind thanks fellows!
~ Daryl
Thank you
If you just want to forbid users to promote themselves to superuser, override YourUserAdmin.get_readonly_fields():
class YourUserAdmin(admin.ModelAdmin):
...
def get_readonly_fields(self, request, obj=None):
if request.user.is_superuser:
return None
try:
return self.readonly_fields + ('is_superuser',)
except:
return ('is_superuser',)
You have to unregister the default User/UserAdmin and then register your own.
admin.site.unregister(User)
admin.site.register(User, YourUserAdmin)
However, the ZEN of admin says:
At it's core, Django's admin is designed for a single activity: trusted users editing structured content.
If the user is not trusted, do not give him edit rights to edit user accounts, period. Even if you hide the superadmin option and the "filter by superadmin status" filter, he can just change your password and log in as you. So, if you need some untrusted users to edit user accounts, forget the admin and write your own dumbed down interface.
No experience with Django but thinking a closure might help you in this situation:
class UserAdmin(UserAdmin):
# adding a new method
def is_superuser(self, request):
"Returns True if the given user is a superuser."
return request.user.is_superuser
def gen_fieldset(self, request):
'''
If request.user.is_supeuser == true then return fieldset generator for superuser.
Else return fieldset generator for normal user.
'''
su = is_superuser(request)
def get_fieldset():
if su:
return super_user_fieldset
else:
return normal_user_fieldset
return get_fieldset
Usage would go like this:
obj = UserAdmin()
request = ... #Generate a normal or super-user request.
fieldset = obj.gen_fieldset(request)
# Sometime later when you want to use the fieldset...
fields = fieldset() # Function will decide which fieldset to give based on gen_fieldset() call earlier.
So the basic idea is that you can configure get_fieldset() ahead of time (via the call to gen_fieldset() where the closure is employed) to return the appropriate fieldset for the user's level. Give the user the function object returned by gen_fieldset() it'll generate the appropriate fieldset at a later time whenever the user calls it.
NOTE: If you've never used closures before I'd suggest googling around for other examples and use scenarios. There may be other solutions that'll fit your situation better (again, not familiar with Django) but that was the first thing that came to my mind.
精彩评论