Django自定义User模型在Admin修改时触发FOREIGN KEY约束失败
解决Django自定义User模型Admin修改时的外键约束错误
看起来你的问题出在Admin配置中没有正确处理PermissionsMixin带来的权限相关字段——虽然你的自定义模型里没有显式声明外键,但PermissionsMixin会自动创建与auth.Group和auth.Permission的多对多关联,这些关联的外键在Admin修改时没有被正确处理,最终触发了外键约束错误。
下面是具体的修复步骤:
1. 修正Admin的字段集配置
你的MyUserAdmin的fieldsets中缺少了PermissionsMixin提供的核心权限字段,但又在filter_horizontal中配置了groups和user_permissions,这会导致表单提交时字段处理逻辑冲突。修改fieldsets,把权限相关字段添加进去:
@admin.register(MyUser) class MyUserAdmin(admin.ModelAdmin): model = MyUser add_form_template = 'admin/auth/user/add_form.html' fieldsets = ( (None, {'fields': ('email', 'password')}), (_('Personal info'), {'fields': ('name', 'organization')}), (_('Permissions'), {'fields': ('is_staff', 'is_superuser', 'can_use_monsoon', 'groups', 'user_permissions')}), ) # 其余配置保持不变
这样Admin表单会正确显示并处理所有权限相关字段,避免提交时的外键约束问题。
2. 调整自定义UserChangeForm的字段配置
你的MyUserChangeForm只包含了部分字段,但UserChangeForm默认需要处理权限相关字段。修改表单类,确保包含所有必要字段:
class MyUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = MyUser fields = ('email', 'password', 'name', 'organization', 'is_staff', 'is_superuser', 'can_use_monsoon', 'groups', 'user_permissions')
或者,如果你不想显式列出所有字段,可以直接继承UserChangeForm的默认字段,只排除不需要的:
class MyUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = MyUser exclude = ('is_admin',) # 移除重叠的is_admin字段,因为已使用is_superuser
3. 验证数据库迁移的正确性
虽然你说已经重新做了迁移,但还是建议确认关联表的外键指向是否正确:
- 打开数据库(比如用DB Browser for SQLite)
- 查看
auth_user_groups和auth_user_user_permissions表的user_id字段,确认其外键指向你的自定义User表(home_myuser)而非默认的auth_user表。
如果外键指向错误,需要彻底重置迁移:
- 删除所有app下的
migrations文件夹(保留__init__.py) - 删除数据库文件
- 重新运行
python manage.py makemigrations - 运行
python manage.py migrate
额外提示
你的自定义模型中有is_admin字段,但PermissionsMixin已经提供了is_superuser字段,两者功能重叠,建议移除is_admin字段,避免逻辑混淆。
内容的提问来源于stack exchange,提问作者JGut
相关产品推荐
相关产品推荐

