'Value of 'list_display[2]' refers to 'first_name', which is not a callable, an attribute of 'UserAdmin', or an attribute on 'authentication.User'

I am trying to add following code to admin.py to make sure that user's password created from django admin will be hashed.

from django.contrib import admin
from .models import *

from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin


class UserAdmin(DjangoUserAdmin):
    pass


# Register your models here.
admin.site.register(User, UserAdmin)

But when i try i got following:

<class 'authentication.admin.UserAdmin'>: (admin.E108) The value of 'list_display[2]' refers to 'first_name', which is not a callable, an attribute of 'UserAdmin', or an attribute or method on 'authentication.User'.

The User model looks like this

class User(AbstractBaseUser, PermissionsMixin):

id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
username = models.CharField(max_length=255, unique=True, db_index=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)

is_verified = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)

created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

balance = models.FloatField(default=0.0)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

objects = UserManager()

def __str__(self):
    return self.email

def tokens(self):
    """" Метод получения токена """
    refresh = RefreshToken.for_user(self)
    return {
        'refresh': str(refresh),
        'access': str(refresh.access_token)
    }

def has_delete_permission(self, *args, **kwargs):
   
    return True if self.is_staff is True else False


Solution 1:[1]

You make use of the UserAdmin, but in the UserAdmin [GitHub], this works with fields like first_name, last_name, etc. that are not defined on your custom User model.

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    # …
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        (_('Permissions'), {
            'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
        }),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )
    # …
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
    list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
    search_fields = ('username', 'first_name', 'last_name', 'email')
    ordering = ('username',)
    filter_horizontal = ('groups', 'user_permissions',)
    # …

You will thus have to rewrite the fieldsets, list_display, and search_fields such that these no longer mention the first_name and last_name fields. You can of course also alter you User model to include these fields, but right now there is simply a mismatch between the UserAdmin and your User model.

Furthermore as, @AbdulAzizBarkat says, this model admin also has a form and add_form, which will include these fields as well.

Solution 2:[2]

I came up with following code of admin.py

from django.contrib import admin
from .models import *

from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.forms import ModelForm


class UserCreationForm(ModelForm):
    class Meta:
        model = User
        fields = ('email',)

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password"])
        if commit:
            user.save()
        return user


class UserAdmin(DjangoUserAdmin):
    # The forms to add and change user instances
    add_form = UserCreationForm
    list_display = ("email",)
    ordering = ("email",)

    fieldsets = (
        (
            None, {
                'fields': (
                    'email',
                    'password',
                    'first_name',
                    'last_name',
                    'balance',
                    'is_verified',
                    'is_active',
                    'is_staff'
                )
            }
        ),
    )
    add_fieldsets = (
        (
            None, {
                'classes': ('wide',),
                'fields': (
                    'email',
                    'password',
                    'first_name',
                    'last_name',
                    'is_superuser',
                    'is_staff',
                    'is_active',
                    'is_verified'
                )
            }
        ),
    )

    filter_horizontal = ()


# Register your models here.
admin.site.register(User, UserAdmin)

Solution 3:[3]

Though the question is old, I am answering the question so that it will help others. In the user model that extends the AbstractBaseUser, a method should be added with the name of the field to display in the class that extends admin.ModelAdminadmin as:

@admin.display(ordering='user__first_name')
    def first_name(self):
    return self.user.first_name

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Alex Nikitin
Solution 3 Bashir M. Saad