我按照dev doc中的描述扩展了django用户模型。我不想保留大部分原始用户模型功能,因此我扩展了AbstractUser类。我在settings.py中定义了:
AUTH_USER_MODEL = 'myapp.CustomUser'
我的用户类:
class CustomUser(AbstractUser):
custom_field = models.ForeignKey('OtherModel')
objects = UserManager()
一切似乎工作正常,但当我尝试通过管理网站进行管理时:
admin.site.register(CustomUser, UserAdmin)
我在管理员CustomUser创建页面上获得此错误(在验证密码确认表单后):
AttributeError: Manager isn't available; User has been swapped for 'myapp.CustomUser'
关键是我需要管理站点管理的这个模型,以便与原始用户模型具有相同的创建过程(使用密码验证的两步过程)。
答案 0 :(得分:20)
您只需要更改表单以添加用户(覆盖clean_username并在get_user_model()上更改用户
完整的工作示例(如果您继承自AbstractUser)
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class MyUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
class MyUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
def clean_username(self):
username = self.cleaned_data["username"]
try:
get_user_model().objects.get(username=username)
except get_user_model().DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
add_form = MyUserCreationForm
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')}),
)
admin.site.register(MyUser, MyUserAdmin)
答案 1 :(得分:13)
我在这个错误中挣扎了好几个小时。对我来说,我需要删除所有对
的引用from django.contrib.auth.models import User
然后将其替换为:
from myapp.models import MyUser as User
这假设您的自定义用户模型位于名为myapp
的应用中,并且您调用了模型MyUser
。
我正在使用as User
,因此我无需更改从User
引用django.contrib.auth.models
对象的现有代码的位置。
艾伦
@aviars
答案 2 :(得分:4)
您可能应该查看官方文档中的完整示例:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example
有一些未发现的问题(例如权限处理),但至少它正在发挥作用。
答案 3 :(得分:0)
来自Django docs:
您还应该为User模型定义自定义管理器。
答案 4 :(得分:0)
子类AbstractUser
已为您处理objects = UserManager()
(第327行为this code on github)。您无需再次在模型中定义它。
我不确定为什么会出现这个错误。但是下面的配置对我来说似乎适用于最新的Dev版本。
Model.py:
class CustomUser(AbstractUser):
custom_field = models.ForeignKey('OtherModel')
# remove : objects = UserManager()
答案 5 :(得分:0)
我找到了一个解决方案: 我不使用UserAdmin在管理站点中注册CustomUser,我使用自定义的ModelAdmin。
class CustomUserAdmin(admin.ModelAdmin):
add_form = CustomUserCreationAdminForm
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2')}
),
)
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(CustomUserAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
})
defaults.update(kwargs)
return super(CustomUserAdmin, self).get_form(request, obj, **defaults)
因为我希望创建一个与更新表单不同的创建表单,所以我在UserAdmin django code中覆盖模型管理员的get_form函数。我还为自定义用户创建了一个自定义创建表单:CustomUserCreationForm
我在django-users邮件列表中收到的回复可能比我的更好: 从管理站点取消注册原始User类,然后使用UserAdmin注册CustomUser:
admin.site.unregister(User)
admin.site.register(CustomUser, UserAdmin)
尚未测试。
编辑:最后一个解决方案不起作用
此致
答案 6 :(得分:0)
UserAdmin
已注册管理User
,在contrib / auth / admin.py结束时
admin.site.register(User, UserAdmin)
如果您想在UserAdmin
注册CustomUser
,我认为您首先必须取消注册User
/ UserAdmin
对:
admin.site.unregister(User)
然后注册您的新模型。鉴于模块加载顺序缺乏控制,您可以创建一个派生自UserAdmin
的类,并使用它管理您的用户模型。如果我正确思考的话,这将每次都有效。