1 year ago

#305459

test-img

Rajat Jog

Hide one of the User.ModelAdmin.fieldsets if User role changes in django

Hi I want to hide some fieldsets in admin if user role changes. In get_queryset() I'm changing queryset if role == 'CMS' I also want to hide Permission fieldset for same role. Here is my admin:

Note: I'm Using list for fieldsets here I pasted touples

from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Permission
from .models import BankAccount
from addresses.models import Address

User = get_user_model()


class AddressInline(admin.TabularInline):
    model = Address
    extra = 0


@admin.register(User)
class UserAdmin(BaseUserAdmin):
    list_display = (
        'id', 'full_name', 'email', 'gender', 'role',
    )
    list_filter = (
        'gender', 'is_staff', 'is_superuser', 'is_active',
    )
    list_display_links = (
        'full_name', 'email',
    )
    search_fields = (
        'email', 'first_name', 'last_name', 'phone_number', 
    )
    
    readonly_fields = (
        'created', 'updated',
    )
    ordering = ('first_name', 'email', 'last_name',)

    fieldsets = [
        ['Credentials', {'fields': ['email', 'phone_number', 'password']}],
        ['Info', {'fields': ['first_name', 'last_name', 'gender', 'role', 'profile_pic', 'created', 'updated']}],
    ]
    add_fieldsets = (
        ('Credentials', {'fields': ('email', 'phone_number', 'password1', 'password2')}),
        ('Info', {'fields': ('first_name', 'last_name', 'gender', 'role', 'profile_pic')}),
        ('Permissions', {'fields': ('is_vendor', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
    )
    inlines = (AddressInline,)
    
    def full_name(self, obj=None):
        return f'{obj.first_name} {obj.last_name}'


    def get_queryset(self, request):
        if request.user.role == 'CMS':
            return self.model.objects.filter(
                role='CUSTOMER', is_staff=False, is_superuser=False
            )
        else:
            return self.model.objects.all()

admin.site.register(Permission)
admin.site.register(BankAccount)

In this admin, in get_queryset() here I'm changing the queryset if role is "CMS". Same like that I don't want to display Permission section from fieldsets option.

I have tried some list options and some tricks like in bellow sample function:

    def get_queryset(self, request):
        if request.user.role == 'CMS' and request.user.is_superuser==False:
            if not any('Permissions' in set for set in self.fieldsets):
                self.fieldsets += [['Permissions', {'fields': ['is_active',]}]]
            return self.model.objects.filter(
                role='CUSTOMER', is_staff=False, is_superuser=False
            )
        else:
            if not any('Permissions' in set for set in self.fieldsets):
                self.fieldsets += [['Permissions', {'fields': ['is_vendor', 'is_staff', 'is_superuser', 'is_active', 'groups', 'user_permissions']}]]
            return self.model.objects.all()

This gives me results in my local machine but not in production server. In production server the permission section get repeated even if then condition added.

Is this because I'm adding this in list_user page and not in change_user page of admin. If so.. then How can I fix this?

How can I achieve that? Thanks in advance

django

django-admin

django-modeladmin

django-3.2

0 Answers

Your Answer

Accepted video resources