[Solved]-Django: Custom User Model fields not appearing in Django admin

20👍

You can append default UserAdmin class with custom fieldsets by adding following to admin.py file:

from django.contrib.auth.admin import UserAdmin

UserAdmin.fieldsets += ('Custom fields set', {'fields': ('name', 'contact')}),

2👍

I think the part you are missing is registering your user model in the app’s admin.py:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

(taken from https://docs.djangoproject.com/en/2.0/topics/auth/customizing/#specifying-a-custom-user-model)

1👍

While the accepted solution does work, it puts all the new fields at the very bottom of the page. It’s nice to be able to append fields to a specific section, and to move fields from one section to another.

I use these two utility functions for appending fields to a fieldset and moving fields from one fieldset to another:

common/utils/admin.py

def append_fields(fieldsets, section, fields):
    """
    fieldsets : tuple
        The fieldsets to append to.
            - fieldsets for editing existing objects
            - add_fieldsets for adding new objects
    section : str or None
        The title of the section. None for the titleless section.
    fields : tuple
        The fields being appended.
    """
    for fieldset in fieldsets:
        if fieldset[0] == section:
            fieldset[1]['fields'] += fields
            break 
    else: # Add new section
        fieldsets = fieldsets + (
            (section, {
                'classes': ('wide',),
                'fields': fields
            }),
        )
    return fieldsets

def move_field(fieldsets, field, from_section, to_section):
    """
    fieldsets : tuple
        The fieldsets to append to.
            - fieldsets for editing existing objects
            - add_fieldsets for adding new objects
    field: str
        The name of the field to move.
    from_section : str or None
        The title of the section from which to remove the field.
    to_section : str or None
        The title of the section in which to add the field.
    """
    for fieldset in fieldsets:
        if fieldset[0] == from_section:
            field_list = list(fieldset[1]['fields'])
            field_list.remove(field) # will raise exception if field not found
            fieldset[1]['fields'] = tuple(field_list)
            break
    else:
        raise Exception(f'No such from fieldset: {from_section}')

    for fieldset in fieldsets:
        print(fieldset)
        if fieldset[0] == to_section:
            fieldset[1]['fields'] = fieldset[1]['fields'] + (field, )
            break
    else:
        raise Exception(f'No such to fieldset: {to_section}')

Then I import it into my CustomUserAdmin class:

users/admin.py

from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin

from common.utils.admin import append_fields, move_field

CustomUser = get_user_model()

class CustomUserAdmin(UserAdmin):
    model = CustomUser

    # Fields for editing existing user
    new_fields = ('dob', 'avatar')
    fieldsets = append_fields(UserAdmin.fieldsets, 'Personal info', new_fields)
    move_field(UserAdmin.fieldsets, 'email', 'Personal info', None)

    # Fields for adding new user
    new_fields = ('email', )
    optional_fields = ('first_name', 'last_name', 'dob')
    add_fieldsets = append_fields(UserAdmin.add_fieldsets, None, new_fields)
    add_fieldsets = append_fields(
        UserAdmin.add_fieldsets, 'Optional Fields', optional_fields
    )


admin.site.register(CustomUser, CustomUserAdmin)

Leave a comment