20

我按照开发文档中的描述扩展了 django 用户模型。我不想保留大部分原始用户模型功能,所以我扩展了 AbstractUser 类。我在settings.py中定义:

AUTH_USER_MODEL = 'myapp.CustomUser'

我的用户类:

class CustomUser(AbstractUser):
  custom_field = models.ForeignKey('OtherModel')
  objects = UserManager()

一切似乎都很好,但是当我尝试让它由管理站点管理时:

admin.site.register(CustomUser, UserAdmin)

我在管理自定义用户创建页面上收到此错误(在验证密码确认表单后):

AttributeError: Manager isn't available; User has been swapped for 'myapp.CustomUser'

关键是我需要这个由管理站点管理的模型,以便拥有与原始用户模型相同的创建过程(密码验证的两步过程)。

4

7 回答 7

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)
于 2012-11-30T08:25:56.007 回答
14

我为这个错误苦苦挣扎了好几个小时。对我来说,我需要删除所有对

from django.contrib.auth.models import User

然后将其替换为:

from myapp.models import MyUser as User

这是假设您的自定义 User 模型位于名为的应用程序中myapp,并且您调用了 model MyUser

我正在使用as User这样我就不必更改Userdjango.contrib.auth.models.

祝你好运!

艾伦

@aviars

于 2013-10-08T00:40:16.310 回答
4

您可能应该查看官方文档中的完整示例:

https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example

有一些未发现的问题(例如权限处理),但至少它是有效的。

于 2013-03-08T10:56:47.903 回答
0

来自Django 文档

您还应该为您的用户模型定义一个自定义管理器。

于 2012-11-26T15:58:28.893 回答
0

子类AbstractUser已经objects = UserManager()为您处理(此代码在 github上的第 327 行)。您无需再次在模型中定义它。

我不确定为什么会出现该错误。但下面的配置似乎适用于我最新的开发版本。

模型.py:

class CustomUser(AbstractUser):
  custom_field = models.ForeignKey('OtherModel')
  # remove : objects = UserManager()
于 2012-11-26T17:02:41.190 回答
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)

因为我想要一个不同于更新表单的创建表单,所以我重写了 Model Admin 的 get_form 函数,就像在UserAdmin django code中所做的那样。我还为我的自定义用户创建了一个自定义创建表单:CustomUserCreationForm

我在 django-users 邮件列表中收到了可能比我的更好的回复:从管理站点取消注册原始 User 类,然后使用 UserAdmin 注册 CustomUser:

admin.site.unregister(User)
admin.site.register(CustomUser, UserAdmin)

尚未测试。

编辑:最后一个解决方案不起作用

问候

于 2012-11-27T21:23:30.590 回答
0

UserAdminUser在 contrib/auth/admin.py 的末尾已经注册为 manage

admin.site.register(User, UserAdmin)

鉴于您想注册UserAdminCustomUser我认为您首先必须取消注册User/UserAdmin对:

admin.site.unregister(User)

然后注册您的新模型。鉴于模块加载顺序缺乏控制,您可以创建一个派生自它的类UserAdmin并使用它来管理您的用户模型。如果我思考得当,这将每次都有效。

于 2013-05-16T16:00:18.237 回答