Exclude fields in Django admin for users other than superuser

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


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

Tags:

Python

Django