如何将关联Profile模型字段合并到Django User管理页面?
一站式编辑Django User与关联Profile模型的Admin页面
问题背景
我定义了与Django内置User模型一对一关联的Profile模型:
class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) verified = models.BooleanField(default=False)
目前修改用户密码、is_active或is_superuser等属性需要在User编辑页面操作,而编辑verified字段得进入Profile的单独页面,想把这两个页面合并成一个表单,实现所有信息的一站式编辑。
尝试方案及遇到的问题
方案1:使用StackedInline
在myapp/admin.py中编写如下代码:
from django.contrib import admin from .models import Profile from django.contrib.auth.models import User class ProfileInline(admin.StackedInline): model = Profile class UserAdmin(admin.ModelAdmin): inlines = (ProfileInline, ) admin.site.unregister(User) admin.site.register(User, UserAdmin)
出现问题:
- 原有的信息分组及标题(如Personal info、Permissions)全部消失,信息展示散乱
- 密码字段直接显示哈希值,丢失了原有的特殊展示形式
- 没有修改密码的入口链接
方案2:手动配置fieldsets
参考Django源码添加fieldsets配置后:
class UserAdmin(admin.ModelAdmin): inlines = (ProfileInline, ) 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"), }, ), ) filter_horizontal = ( "groups", "user_permissions", ) admin.site.unregister(User) admin.site.register(User, UserAdmin)
出现问题:
- 顶部恢复了分组及标题,但密码字段仍显示异常,没有修改密码的链接,且
verified字段未显示 - 页面下方出现重复的用户信息(无分组标题),仅附带
verified字段,属于冗余内容
正确解决方案
核心是继承Django自带的UserAdmin而非基础的ModelAdmin,这样可以完整保留默认User管理页面的所有特性,再把Profile作为Inline整合进去。
修改后的myapp/admin.py代码:
from django.contrib import admin from .models import Profile from django.contrib.auth.admin import UserAdmin # 继承自带的UserAdmin from django.contrib.auth.models import User # 定义Profile的Inline class ProfileInline(admin.StackedInline): model = Profile can_delete = False # 可选,避免误删关联的Profile verbose_name_plural = "用户资料" # 可选,自定义显示名称 # 自定义UserAdmin,继承自带的实现 class CustomUserAdmin(UserAdmin): inlines = (ProfileInline,) # 替换默认的User注册 admin.site.unregister(User) admin.site.register(User, CustomUserAdmin)
效果说明
- 保留默认User编辑页面的所有特性:分组展示、密码的特殊显示样式、修改密码的入口链接
Profile的verified字段会以Inline的形式整合到User编辑页面中(默认在页面下方),实现一站式编辑所有用户相关信息
内容的提问来源于stack exchange,提问作者Omid Shojaee
相关产品推荐
相关产品推荐

