I'm trying to add some extra fields into the django.contrib.auth.models
User model. I'll be using this custom User model throughout my project. I used AbstractUser
to add name
and contact
fields.
class User(AbstractUser):
name = models.CharField(_('Name of User'), blank=True, max_length=255)
contact = models.CharField(max_length=20, blank=True)
def __str__(self):
return self.username
In my settings.py
, I added to the apps.authentication
, which is my app:
INSTALLED_APPS = [ 'apps.authentication', ...]
I also specified my AUTH_USER_MODEL
:
AUTH_USER_MODEL = 'authentication.User'
I then ran migrations and it worked (I checked my local db; new tables were made). However, when I access it using the Django admin, the name
and contact
fields were nowhere to be found. How do I make the fields appear?
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')}),
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)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With