Custom UserAdmin doesn't work I get "Key 'password1' not found in 'UserForm'."

I have the custom UserAdmin model (which is based on CustomUserModel). See below on the full code.

When I set:

    fieldsets = (
        (None, {'fields': ('email', 'password1', 'password2')}), . . . other code, see below

I can add user on admin interface. But I get this error when I try to change user on DjangoAdmin:

# KeyError at /admin/users/user/4/change/

"Key 'password1' not found in 'UserForm'. Choices are: address, birth_date, city, country, email, first_name, groups, is_active, is_staff, last_name, password, phone_nr, postal_code, profession_title, user_permissions, workplace."

But when I set

    fieldsets = (
        (None, {'fields': ('email', 'password',)}), . . . other code, see below

Then I can access and change user. But then I get the “add user” form like this, and I can’t add user despite all forms are filled correctly:

What is the problem? How can I fix that?

The code for Custom UserAdmin model.

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

from .models import User

class UserAdmin(DjangoUserAdmin):

    """Define admin model for custom User model with no email field."""

    fieldsets = (
        (None, {'fields': ('email', 'password1', 'password2')}),
        (('Personal info'), {'fields': ('first_name', 'last_name', 'profession_title',
        'country', 'city', 'postal_code','address','workplace', 'phone_nr', 'birth_date')}),
        (('Permissions'), {'fields': ('is_active', 'is_staff', 'groups',
                                       'user_permissions')}),
        (('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )

    readonly_fields=('last_login', 'date_joined')
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2', 'first_name', 'last_name', 'profession_title',
        'country', 'city', 'postal_code','address','workplace', 'phone_nr', 'birth_date'),
        }),
    )

    list_display = ('email', 'first_name', 'last_name', 'profession_title', 'is_staff')
    search_fields = ('email', 'first_name', 'last_name')
    ordering = ('email', 'first_name', 'last_name', 'profession_title', 'is_staff')
    def has_change_permission(self, request, obj=None):

        if not request.user.is_superuser:
            if obj:
                if isinstance(obj, User):
                    if obj.is_staff:
                        return False
        else:
            return True
        return True

   
    def has_delete_permission(self, request, obj=None):
        if not request.user.is_superuser:
            if obj:
                if isinstance(obj, User):
                    if obj.is_staff:
                        return False
        else:
            return True
        return True

   

    def change_view(self, request, object_id, extra_context=None):
        if request.user.is_superuser:
            self.exclude = ('password1','password2',)
        else:
            self.exclude = ('email', 'password1', 'password2', 'user_permissions', 'groups',)
        return super().change_view(request, object_id, extra_context)
       
    def get_fieldsets(self, request, obj=None):
        if not request.user.is_superuser:
            fieldsets = (
                (None, {'fields': ('email', 'password1', 'password2')}),
                (('Personal info'), {'fields': ('first_name', 'last_name', 'profession_title',
                'country', 'city', 'postal_code','address','workplace', 'phone_nr', 'birth_date')}),
                (('Permissions'), {'fields': ('is_active',)}),
                (('Important dates'), {'fields': ('last_login', 'date_joined')}),
            )
            return fieldsets
        else:
            return self.fieldsets
   
    def get_readonly_fields(self, request, obj=None):
            if not request.user.is_superuser:
                return ('first_name', 'last_login', 'date_joined', 'birth_date')
            else:
                return self.readonly_fields

I fixed it, I just had to change get_fieldsets and make sure it returns self.add_fieldset if obj is None, and fieldset if it’s not None and instance of User model.

Below is the updated code:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.contrib.auth.models import Group
from .models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm

class UserAdmin(DjangoUserAdmin):
    """Define admin model for custom User model with no email field."""
    fieldsets = (
        (None, {'fields': ('email', 'password',)}),
        (('Personal info'), {'fields': ('first_name', 'last_name', 'profession_title',
        'country', 'city', 'postal_code','address','workplace', 'phone_nr', 'birth_date')}),
        (('Permissions'), {'fields': ('is_active', 'is_staff', 'groups',
                                       'user_permissions')}),
        (('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )
    readonly_fields=('last_login', 'date_joined')
    add_fieldsets = (

        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2', 'first_name', 'last_name', 'profession_title',
        'country', 'city', 'postal_code','address','workplace', 'phone_nr', 'birth_date'),
        }),
    )

    list_display = ('email', 'first_name', 'last_name', 'profession_title', 'is_staff')
    search_fields = ('email', 'first_name', 'last_name')
    ordering = ('email', 'first_name', 'last_name', 'profession_title', 'is_staff')
    def has_change_permission(self, request, obj=None):
        if not request.user.is_superuser:
            if obj:
                if isinstance(obj, User):
                    if obj.is_staff:
                        return False
        else:
            return True
        return True
   

    def has_delete_permission(self, request, obj=None):
        if not request.user.is_superuser:
            if obj:
                if isinstance(obj, User):
                    if obj.is_staff:
                        return False
        else:
            return True
        return True
  

    def change_view(self, request, object_id, extra_context=None):
        if request.user.is_superuser:
            self.exclude = ('password', )
        else:
            self.exclude = ('email', 'password', 'user_permissions', 'groups',)
        return super().change_view(request, object_id, extra_context)
       
    def get_fieldsets(self, request, obj=None):
        if not request.user.is_superuser:
            if obj:
                if isinstance(obj, User):
                    fieldsets = (
                        (None, {'fields': ('email', 'password',)}),
                        (('Personal info'), {'fields': ('first_name', 'last_name', 'profession_title',
                        'country', 'city', 'postal_code','address','workplace', 'phone_nr', 'birth_date')}),
                        (('Permissions'), {'fields': ('is_active',)}),
                        (('Important dates'), {'fields': ('last_login', 'date_joined')}),
                    )
                    return fieldsets
            else:
                return self.add_fieldsets
        else:
            if obj:
                if isinstance(obj, User):
                    return self.fieldsets
            else:
                return self.add_fieldsets

   
    def get_readonly_fields(self, request, obj=None):
            if not request.user.is_superuser:
                return ('first_name', 'last_login', 'date_joined', 'birth_date')
            else:
                return self.readonly_fields
1 Like