18๐
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!
19๐
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:
- [Django]-Rendering a value as text instead of field inside a Django Form
- [Django]-Removing 'Sites' from Django admin page
- [Django]-Http POST drops port in URL
10๐
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
- [Django]-Django-nonrel + Django-registration problem: unexpected keyword argument 'uidb36' when resetting password
- [Django]-Django-rest-framework returning 403 response on POST, PUT, DELETE despite AllowAny permissions
- [Django]-Django Generic Views using decorator login_required
0๐
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)
- [Django]-Django.db.utils.ProgrammingError: relation "bot_trade" does not exist
- [Django]-Filtering dropdown values in django admin
- [Django]-Django: For Loop to Iterate Form Fields
0๐
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.
- [Django]-Django admin default filter
- [Django]-Passing STATIC_URL to file javascript with django
- [Django]-Removing 'Sites' from Django admin page
0๐
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()
- [Django]-Django models avoid duplicates
- [Django]-Django apps aren't loaded yet when using asgi
- [Django]-Django character set with MySQL weirdness