在Django中扩展AbstractUser实现用户配置文件的正确方法及Admin显示问题咨询
Hey there! Let's break down your questions and fix the issues you're facing step by step.
First: Are your two implementation approaches correct?
1. The separate CustomUser + Profile pattern
This is totally correct and actually a recommended best practice in Django. By keeping core authentication fields (from AbstractUser) in one model and extra user metadata (bio, city, avatar) in a separate Profile model with a OneToOneField, you keep your user model clean and make future extensions easier. Using settings.AUTH_USER_MODEL for the relationship is smart too—it makes your code flexible if you ever need to switch user models later.
2. The second approach (adding fields directly to CustomUser but with a redundant OneToOneField)
This is incorrect. When you inherit from AbstractUser, you're already building on top of Django's base user model—adding a OneToOneField to settings.AUTH_USER_MODEL (which points to your own CustomUser) creates a circular relationship that serves no purpose. If you want to embed extra fields directly in the user model, you just need to add those fields to CustomUser without the extra user field, like this:
from django.db import models from django.contrib.auth.models import AbstractUser from django.conf import settings class CustomUser(AbstractUser): bio = models.CharField(max_length=480, blank=True) city = models.CharField(max_length=40) avatar = models.ImageField(null=True, blank=True) def __str__(self): return self.username
Second: Fixing the Django Admin issue (no custom fields showing up)
Django's default UserAdmin doesn't automatically pick up your custom fields—you need to explicitly configure it to display them. Here's how to handle both valid approaches:
Option 1: If you're using the separate CustomUser + Profile pattern
Update your admin.py to register both models and link them so you can view/edit profiles from the user page:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser, Profile # Inline to show Profile fields directly on the CustomUser edit page class ProfileInline(admin.StackedInline): model = Profile can_delete = False verbose_name_plural = "User Profile" # Customize the CustomUser admin to include the Profile inline class CustomUserAdmin(UserAdmin): inlines = (ProfileInline,) list_display = ('username', 'email', 'is_staff') # Add fields you want to see in the list view # Register the models admin.site.register(CustomUser, CustomUserAdmin) admin.site.register(Profile)
Option 2: If you're using the extended CustomUser model
Update your admin.py to tell UserAdmin about your custom fields:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser class CustomUserAdmin(UserAdmin): # Show custom fields in the user list view list_display = ('username', 'email', 'city', 'is_staff') # Add custom fields to the edit page (merge with default sections) fieldsets = UserAdmin.fieldsets + ( ("Extra Personal Info", {"fields": ("bio", "city", "avatar")}), ) # Add custom fields to the "add user" page add_fieldsets = UserAdmin.add_fieldsets + ( ("Extra Personal Info", {"fields": ("bio", "city", "avatar")}), ) admin.site.register(CustomUser, CustomUserAdmin)
Quick additional checks
- Make sure
AUTH_USER_MODELis set: In your project'ssettings.py, add this line (replaceyourappwith your app name):AUTH_USER_MODEL = "yourapp.CustomUser" - Re-run migrations if you changed models: After fixing your models, run:
python manage.py makemigrations python manage.py migrate - Configure media for
ImageField: To handle avatar uploads, add these tosettings.py:
And add this to your project'sMEDIA_ROOT = BASE_DIR / "media" MEDIA_URL = "/media/"urls.py(for development only):from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # Your existing URLs ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
内容的提问来源于stack exchange,提问作者Amit pratap singh

