I have a simple MyUser
class with PermissionsMixin
. user.is_superuser
equals True
only for superusers. I\'d like to be able t
According to Django Docs, the correct way is to create a ModelForm for superusers and another for normal users. Then you specify each form in the get_form method of your ModelAdmin:
class MyModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs['form'] = MySuperuserForm
else:
kwargs['form'] = MyNormalForm
return super(MyModelAdmin, self).get_form(request, obj, **kwargs)
If I understand you correctly, what you want to do is override the get_form method for the ModelAdmin. Base on the example from django documentation, it would look something like this:
class MyUserAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
self.exclude = []
if not request.user.is_superuser:
self.exclude.append('Permissions') #here!
return super(MyUserAdmin, self).get_form(request, obj, **kwargs)
Now you might need to hack around a little and maybe override the save method as well. I did something similar not long ago, it's not so complicated (and the docs are fantastic).
There might be a simpler solution but your question is kinda general and you didn't share your user model, so I can't tell you exactly how to work this out. I hope this helps!
Django now has a get_exclude
method on ModelAdmin for excluding fields programmatically.
It takes the current request and the object (if any) as argument. You can put a check there on the request argument to see if they're a superuser and check
class MyModelAdmin(admin.ModelAdmin):
def get_exclude(self, request, obj=None):
excluded = super().get_exclude(request, obj) or [] # get overall excluded fields
if not request.user.is_superuser: # if user is not a superuser
return excluded + ['extra_field_to_exclude']
return excluded # otherwise return the default excluded fields if any
Starting Django 1.7 you can replace the base class of your model admin with something like:
class SuperuserAwareModelAdmin(admin.ModelAdmin):
superuser_fields = None
superuser_fieldsets = None
def get_fieldsets(self, request, obj = None):
if request.user.is_superuser and self.superuser_fieldsets:
return (self.fieldsets or tuple()) + self.superuser_fieldsets
return super(SuperuserAwareModelAdmin, self).get_fieldsets(request, obj)
def get_fields(self, request, obj = None):
if request.user.is_superuser and self.superuser_fields:
return (self.fields or tuple()) + self.superuser_fields
return super(SuperuserAwareModelAdmin, self).get_fields(request, obj)
Example:
class MyModelAdmin(SuperuserAwareModelAdmin):
superuser_fieldsets = (
(_('Permissions'), {'fields': ('is_staff', )}),
)
The SuperuserAwareModelAdmin
base class can also be created as a mixin.
Accepted answer is close but as others point out, get_form is called multiple times on the same instance of the Admin model and the instance is reused, so you can end up with fields repeated or other users seeing the fields after self.fields is modified. Try this out in Django <=1.6:
class MyAdmin(admin.ModelAdmin):
normaluser_fields = ['field1','field2']
superuser_fields = ['special_field1','special_field2']
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
self.fields = self.normaluser_fields + self.superuser_fields
else:
self.fields = self.normaluser_fields
return super(MyAdmin, self).get_form(request, obj, **kwargs)
Looks like, Django 1.7 introduces a get_fields() method you can override which is a much nicer approach:
https://github.com/django/django/blob/d450af8a2687ca2e90a8790eb567f9a25ebce85b/django/contrib/admin/options.py#L276
I solved it this way inspired by previous answers. In my example only a superuser may create a superuser. If it is not superuser the checkbox in the form is missing. It works for me and I hope it is correct:
def get_form(self, form_class=form_class):
if self.request.user.is_superuser is False:
self.form_class.base_fields.pop('is_superuser')
return super(AccountCreateView, self).get_form()