Custom user: how to change the admin forms?

I extended the standard user by inheriting from AbstractUser. However I cannot seem to be able to make any changes to the UserForm in the admin. This is what I tried:

class CustomUserChangeForm(UserChangeForm):
    class Meta:
        model = User
        exclude = []
        # exclude = ['is_staff']
        readonly_fields = ['date_joined']

The field date_joined is not readonly. When I don’t have either fields or exclude in the form, I get an error. But when I put any fields in those lists, I get an error as well. If for instance I put in is_staff as in the outcommented line, I get the error:

“Key ‘is_staff’ not found in ‘UserForm’. Choices are: date_joined, email, first_name, groups, is_active, is_superuser, last_login, last_name, password, user_permissions, username.”

It will always list all the model properties except the one that I put in exclude. Also, all the extra model properties that I added are being ignored.

from django.contrib.auth.models import AbstractUser
from django.db import models as m


class User(AbstractUser):
    # user credentials, needed for bills (PDF generator)
    business_phone = m.CharField(max_length=256, blank=True)  # telephone number for business contacts
    # billing_address = m.ForeignKey(Address, on_delete=m.CASCADE)
    tax_reference = m.CharField(max_length=256, blank=True)  # Steuernummer
    # bank account
    IBAN = m.CharField(max_length=256, blank=True)
    BIC = m.CharField(max_length=256, blank=True)
    bank_name = m.CharField(max_length=256, blank=True)

Are you importing the right User model in your admin.py file? (It’s this type of situation that explains why I suggest never reusing the name User as a model, even when creating a custom user. Issues similar to this can be really confusing.)

I wondered about that as well, but I double checked. I’m pretty certain, I’m importing the right user. In my admin.py, when hovering over the import, it gives me this:
usermodell
My project is called cu and the app with the user model is called users. I’m inheriting from AbstractUser.
From the way the error works, I was wondering, if Django is still using the standard UserChangeForm somehow.

What does your ModelAdmin class look like? Are you specifying this form in that class?

from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError
from .models import User


class CustomUserCreationForm(UserCreationForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    class Meta:
        model = User
        exclude = []
        readonly_fields = ['date_joined']


class CustomUserChangeForm(UserChangeForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    disabled password hash display field.
    """
    class Meta:
        model = User
        exclude = []
        # exclude = ['is_staff']
        readonly_fields = ['date_joined']
        # fields = ["email", "password", "is_active", "bank_name"]


class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = CustomUserChangeForm
    add_form = CustomUserCreationForm


admin.site.register(User, UserAdmin)

I have tried both inhereting from the UserForms and from ModelForm. It doesn’t not make a difference. I wonder if I have to change the UserManager? In the manual it says that’s not necessary when just extending the standard user model. But maybe the standard form is coming from the Manager?

In the admin, are you selecting the link for User from your app, or from the auth app?
(What’s the url being generated for your update view?)

The Manager doesn’t have anything to do with this at all.

You might want to make sure there’s no confusion by unregistering the auth User from the admin.

The link in the admin is pointing to my custom users app.

http://127.0.0.1:8000/admin/users/user/1/change/

I tried unregistering the user, but when I do that I get an error telling me that user is not registered.

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

When I delete the register command, the User model disappears from the admin as it should.

I think I found out where it happens. This is the UserAdmin from Django itself.

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    add_form_template = "admin/auth/user/add_form.html"
    change_user_password_template = None
    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")}),
    )
    add_fieldsets = (
        (
            None,
            {
                "classes": ("wide",),
                "fields": ("username", "password1", "password2"),
            },
        ),
    )
    form = UserChangeForm
    add_form = UserCreationForm
    change_password_form = AdminPasswordChangeForm
    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",
    )

This is my custom UserAdmin:

class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = CustomUserChangeForm
    add_form = CustomUserCreationForm

So I’m changing the Form on my custom UserAdmin while the parent model is still defining all the fieldsets.

I have now gone through all the fields that the django UserAdmin provides and I can finally shape the form in which ever way I want.