Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude fields in Django admin for users other than superuser

Tags:

I have a simple MyUser class with PermissionsMixin. user.is_superuser equals True only for superusers. I'd like to be able to do something similar to this in my admin.py:

    if request.user.is_superuser:
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            ('Permissions', {'fields': ('is_admin','is_staff')}),
            ('Place', {'fields': ('place',)}),
            ('Important dates', {'fields': ('last_login',)}),
        )
    else:
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            #('Permissions', {'fields': ('is_admin','is_staff')}),
            ('Place', {'fields': ('place',)}),
            ('Important dates', {'fields': ('last_login',)}),
        )

Basically I want my users to be able to create other users, but not give them admin or stuff permissions. Only superusers should be able to do that.

like image 265
Marek Szmalc Avatar asked Oct 05 '13 21:10

Marek Szmalc


People also ask

How do I restrict admin in Django?

Django admin allows access to users marked as is_staff=True . To disable a user from being able to access the admin, you should set is_staff=False . This holds true even if the user is a superuser. is_superuser=True .

How do you make a field non mandatory in Django admin?

The simplest way is by using the field option blank=True (docs.djangoproject.com/en/dev/ref/models/fields/#blank).

What is admin Modeladmin in Django?

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.


2 Answers

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

like image 197
Matt Avatar answered Oct 21 '22 15:10

Matt


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!

like image 39
yuvi Avatar answered Oct 21 '22 17:10

yuvi