How to exclude fields in get_fieldsets() based on user type in Django admin

Viewed 2495

I'm trying to use get_fieldsets to organize admin model pages. Using fieldsets is pretty satisfying, but I'm stuck with how to exclude some fields. Currently, I used if condition to check user type, and then return different fieldsets based on user type. I'm having the same codes to be repeated because of that. Is there a way to exclude a few fields in get_fieldsets?

admin.py

class StoreAdmin(admin.ModelAdmin):
    ...
    def get_fieldsets(self, request, obj=None):
        fieldsets = copy.deepcopy(super(StoreAdmin, self).get_fieldsets(request, obj))
        if request.user.is_superuser:
            return (
                [
                    ('Basic Information', {
                        'fields': (
                            ('status', 'review_score', 'typ'),
                            ('businessName', 'relatedName'),
                            ('mKey'),
                        )
                    }),
                    ('Additional Options', {
                        'fields': (
                            ('affiliate_switch', 'is_affiliated', 'affiliate',),
                        )
                    }),
                ]
            )
        else:
            return (
                [
                    ('Basic Information', {
                        'fields': (
                            ('status', 'review_score', 'typ'),
                            ('businessName', 'relatedName'),
                            ('mKey'),
                        )
                    }),
                ]
            )
2 Answers

If you only want to exclude fields you can use get_fields instead as following:

def get_fields(self, request, obj=None):
    fields = super(ClientAdmin, self).get_fields(request, obj)
    if obj:
        fields_to_remove = []
            if request.user.is_superuser:
                fields_to_remove = ['field1', 'field2', 'etc', ]
            for field in fields_to_remove:
                fields.remove(field)
        return fields

Edit: Same logic could be used for get_fieldsets

My way to solve this:

def get_fieldsets(self, request, obj=None):
   fieldsets = super(AccountInline, self).get_fieldsets(request, obj)
   fields_to_remove = ['field1', 'field2', 'etc', ]
   if request.user.is_superuser:
      # select your way, my:[3][1]
      fieldsets[3][1]['fields'] = tuple(x for x in fieldsets[3][1]['fields'] if not x in fields_to_remove)
   return fieldsets
Related