Django Admin is using the wrong UserManager

Viewed 51

I have created a custom user class:

class User(AbstractUser):
    objects = UserDashManager()
    custom_field = models.CharField(max_length=84)

And a UserManager to populate that field at creation:

class UserDashManager(UserManager):

    def create_user(self, username, email, password, **extra_fields):
        extra_fields.setdefault('custom_field', 'custom field value')
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(username, email, password, **extra_fields)

I have registered User in admin.py:

class CustomAdmin(UserAdmin):
    model = User
    list_display = ['username', 'email', 'first_name', 'last_name','is_staff','custom_field']

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

But if I use the admin page http://127.0.0.1:8000/admin/my_app/user/add/ then the user's custom field is blank.

I have done the migration, so the field is in the database.

I have set AUTH_USER_MODEL = 'my_app.User' in settings.py.

If I create the user in the django shell then the field gets populated, just not from the admin page. Is there something else I need to register? Do I need to create a custom form?

How can I get the admin site to use the correct UserManager?


Edit

I have tried changing the User Manager to this:

class UserDashManager(UserManager):

    def create_user(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        user = self._create_user(username, email, password, **extra_fields)
        user.custom_field = 'custom field value'
        user.save()
        return user

But still no luck

In case it's important: I'm using Django 3.2

1 Answers

I have replaced the form that Django admin uses, inheriting from UserCreationForm

from django.contrib.auth.forms import UserCreationForm, UsernameField
from .models import User

class UserDashCreationForm(UserCreationForm):

    class Meta:
        model = User
        fields = ("username",)
        field_classes = {"username": UsernameField}
        
    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        user.custom_field = 'custom field value'
        if commit:
            user.save()
        return user     

Then in admin.py I changed CustomAdmin to reference that form:

class CustomAdmin(UserAdmin):
    model = User
    list_display = ['username', 'email', 'first_name', 'last_name','is_staff','custom_field']
    add_form = UserDashCreationForm
Related