django admin get_list_filter

this is my get_list_filter method in user admin

    def get_list_filter(self, request):
        list_filter = self.list_filter

        if request.user.is_superuser:
            list_filter.append('is_superuser')

        return list_filter

the problem is after each time i call user admin panel in browser, an new is_superuser field wil be add to list filter.

just like this:
first time: list_filter = [<class 'octopus.accounts.admin.user.UserInfoSearch'>, <class 'octopus.accounts.admin.user.UserEmailSearch'>, 'is_staff', 'groups', <class 'octopus.accounts.admin.user.UserRoleStatusFilter'>, <class 'octopus.accounts.admin.reward.UserBuildingFilter'>, <class 'octopus.accounts.admin.user.WorkmanStateFilter'>, 'is_superuser']

second time: list_filte = [<class 'octopus.accounts.admin.user.UserInfoSearch'>, <class 'octopus.accounts.admin.user.UserEmailSearch'>, 'is_staff', 'groups', <class 'octopus.accounts.admin.user.UserRoleStatusFilter'>, <class 'octopus.accounts.admin.reward.UserBuildingFilter'>, <class 'octopus.accounts.admin.user.WorkmanStateFilter'>, 'is_superuser', 'is_superuser']

third time: list_filte = [<class 'octopus.accounts.admin.user.UserInfoSearch'>, <class 'octopus.accounts.admin.user.UserEmailSearch'>, 'is_staff', 'groups', <class 'octopus.accounts.admin.user.UserRoleStatusFilter'>, <class 'octopus.accounts.admin.reward.UserBuildingFilter'>, <class 'octopus.accounts.admin.user.WorkmanStateFilter'>, 'is_superuser', 'is_superuser', 'is_superuser']

as you see is_superuser is added each time!

Try this:

def get_list_filter(self, request):
    list_filter = list(self.list_filter)  # Create a new list from self.list_filter

    if request.user.is_superuser and 'is_superuser' not in list_filter:
        list_filter.append('is_superuser')

    return list_filter

thanks for the solution, but i want to know why this happened!

This is the mistake.

You’re getting a reference to the actual class attribute, and so you’re mutating that attribute in the class, not a local copy of it. (That attribute is a class attribute, not an instance attribute.)

I expect that after doing this, if you were to log out and log back in as a non-superuser, you would still see this filter being shown.

You want to make a copy (new instance) of that attribute to modify it for that instance and return that copy.

1 Like

The result you want can be expressed as follows:

a = 0~9
if a is greater than 5, add 1 to a

a = {some function}
if 5 < a:
  a += 1

same as

def get_list_filter(self, request):
  list_filter = self.list_filter
  if 'is_superuser' not in list_filter and request.user.is_superuser:
    list_filter.append('is_superuser')
  return list_filter

But, your code just add 1 to the size of a

a = {some function}
a += 1

same as

def get_list_filter(self, request):
  list_filter = self.list_filter
  if request.user.is_superuser:
    list_filter.append('is_superuser')
  return list_filter
1 Like

yes you are right about this I expect that after doing this, if you were to log out and log back in as a non-superuser, you would still see this filter being shown.

thanks for the explanation